برنامه نویسی

یک «نقشه» کمی بهتر، خواندن کد شما را آسان‌تر می‌کند…

Summarize this content to 400 words in Persian Lang
در جاوا اسکریپت، Map یک کلاس داخلی بسیار مفید است که یک جستجوی O(1) بین یک کلید و یک مقدار ایجاد می کند.

const myMap = new Map()

for(const file of files) {
const [,extension] = file.name.split(“.”)
if(!myMap.has(extension)) {
myMap.set(extension, [])
}
myMap.get(extension).push(file)
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

می‌توانید از Maps برای انواع کارهایی که احتمالاً مرتباً انجام می‌دهید استفاده کنید:

ایجاد لیست های گروه بندی شده از داده ها، مانند مثال بالا گروه بندی بر اساس پسوند فایل
جمع‌آوری داده‌ها، مانند شمارش یا جمع کردن مقادیر در طیفی از کلیدها

const items = [‘apple’,’apple’,’orange’,’banana’,’apple’];
const counts = new Map();
for (const item of items) {
counts.set(item, (counts.get(item) || 0) + 1);
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد جستجوهای سریع برای استفاده در مراحل بعدی

const users = [
{id:1,name:’A’,role:’admin’},
{id:2,name:’B’,role:’user’},
{id:3,name:’C’,role:’user’}
];
const userMap = new Map();
for (const u of users) {
userMap.set(u.id, u);
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نقشه به استفاده از یک شی ساده ترجیح داده می شود ({}) به چند دلیل، تا زمانی که مجبور نباشید نتیجه را با استفاده از a ذخیره کنید stringify:

می تواند کلیدهایی را بگیرد که رشته ای نیستند
حتی اگر از کلیدهای رشته ای استفاده می کنید، کمی سریعتر از یک شیء است

ممکن است نگرانی‌های زیادی وجود داشته باشد، اما اگر شیئی که در نقشه ذخیره می‌کنید نیاز به ساخت دارد، که از یک آرایه ساده گرفته تا یک شی پیچیده است، این باید با کدی که از آن استفاده می‌کند، آمیخته شود.

const map = new Map()

for(const item of items) {
if(!map.has(item.type)) {
const newType = new Type(item.type, getInfoForType(item.type))
map.set(item.type, newType)
}
map.get(item.type).doSomething(item)

}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این “می تواند” خوب است، اما اگر نیاز به به روز رسانی یا مقداردهی اولیه در چندین مکان داشته باشید، نگه داشتن DRY دشوارتر می شود.

به همین دلیل من از یک کلاس MapPlus استفاده می کنم، که پسوندی برای Map است که یک تابع اولیه کلید گم شده را ارائه می دهد که می تواند به سازنده یا به عنوان پارامتر دوم برای get اگر مقداردهی اولیه به اطلاعات زمینه فراتر از کلید نیاز داشته باشد.

class MapPlus extends Map {
constructor(missingFunction) {
super()
this.missingFunction = missingFunction
}

get(key, createIfMissing = this.missingFunction) {
let result = super.get(key)
if (!result && createIfMissing) {
result = createIfMissing(key)
if (result && result.then) {
const promise = result.then((value) => {
super.set(key, value)
return value
})
super.set(key, promise)
} else {
super.set(key, result)
}
}
return result
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با این کار فقط می توانید کارهایی مانند:

const map = new MapPlus(()=>[])

for(const item of items) {
map.get(item.type).push(item)
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر کلید از دست رفته باشد، فقط یک آرایه خالی ایجاد می کند، اما خود حلقه ساده و تمیز نگه داشته می شود و فقط به ایجاد لیست مربوط می شود.

من اغلب به دو سطح از این نیاز دارم، بنابراین نقشه ها را به این صورت تعریف می کنم:

const map = new MapPlus(()=>new MapPlus(()=>[]))
for(const item of items) {
map.get(item.type).get(item.subType).push(item)
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تابع سازنده می شود key استفاده می شود بنابراین ما همچنین می توانیم انجام دهیم:

const map = new MapPlus((type)=>new Type(type, getInfoForType(type))

for(const item of items) {
map.get(item.type).doSomething(item)
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در جاوا اسکریپت، Map یک کلاس داخلی بسیار مفید است که یک جستجوی O(1) بین یک کلید و یک مقدار ایجاد می کند.

const myMap = new Map()

for(const file of files) {
    const [,extension] = file.name.split(".")
    if(!myMap.has(extension)) {
        myMap.set(extension, [])
    }
    myMap.get(extension).push(file)
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

می‌توانید از Maps برای انواع کارهایی که احتمالاً مرتباً انجام می‌دهید استفاده کنید:

  • ایجاد لیست های گروه بندی شده از داده ها، مانند مثال بالا گروه بندی بر اساس پسوند فایل

  • جمع‌آوری داده‌ها، مانند شمارش یا جمع کردن مقادیر در طیفی از کلیدها

const items = ['apple','apple','orange','banana','apple'];
const counts = new Map();
for (const item of items) {
  counts.set(item, (counts.get(item) || 0) + 1);
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  • ایجاد جستجوهای سریع برای استفاده در مراحل بعدی
const users = [
  {id:1,name:'A',role:'admin'},
  {id:2,name:'B',role:'user'},
  {id:3,name:'C',role:'user'}
];
const userMap = new Map();
for (const u of users) {
  userMap.set(u.id, u);
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نقشه به استفاده از یک شی ساده ترجیح داده می شود ({}) به چند دلیل، تا زمانی که مجبور نباشید نتیجه را با استفاده از a ذخیره کنید stringify:

  • می تواند کلیدهایی را بگیرد که رشته ای نیستند
  • حتی اگر از کلیدهای رشته ای استفاده می کنید، کمی سریعتر از یک شیء است

ممکن است نگرانی‌های زیادی وجود داشته باشد، اما اگر شیئی که در نقشه ذخیره می‌کنید نیاز به ساخت دارد، که از یک آرایه ساده گرفته تا یک شی پیچیده است، این باید با کدی که از آن استفاده می‌کند، آمیخته شود.


const map = new Map()

for(const item of items) {
   if(!map.has(item.type)) {
       const newType = new Type(item.type, getInfoForType(item.type))
       map.set(item.type, newType)
   }
   map.get(item.type).doSomething(item)

}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این “می تواند” خوب است، اما اگر نیاز به به روز رسانی یا مقداردهی اولیه در چندین مکان داشته باشید، نگه داشتن DRY دشوارتر می شود.

به همین دلیل من از یک کلاس MapPlus استفاده می کنم، که پسوندی برای Map است که یک تابع اولیه کلید گم شده را ارائه می دهد که می تواند به سازنده یا به عنوان پارامتر دوم برای get اگر مقداردهی اولیه به اطلاعات زمینه فراتر از کلید نیاز داشته باشد.

class MapPlus extends Map {
    constructor(missingFunction) {
        super()
        this.missingFunction = missingFunction
    }

    get(key, createIfMissing = this.missingFunction) {
        let result = super.get(key)
        if (!result && createIfMissing) {
            result = createIfMissing(key)
            if (result && result.then) {
                const promise = result.then((value) => {
                    super.set(key, value)
                    return value
                })
                super.set(key, promise)
            } else {
                super.set(key, result)
            }
        }
        return result
    }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با این کار فقط می توانید کارهایی مانند:

const map = new MapPlus(()=>[])

for(const item of items) {
    map.get(item.type).push(item)
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر کلید از دست رفته باشد، فقط یک آرایه خالی ایجاد می کند، اما خود حلقه ساده و تمیز نگه داشته می شود و فقط به ایجاد لیست مربوط می شود.

من اغلب به دو سطح از این نیاز دارم، بنابراین نقشه ها را به این صورت تعریف می کنم:

const map = new MapPlus(()=>new MapPlus(()=>[]))
for(const item of items) {
   map.get(item.type).get(item.subType).push(item)
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تابع سازنده می شود key استفاده می شود بنابراین ما همچنین می توانیم انجام دهیم:

const map = new MapPlus((type)=>new Type(type, getInfoForType(type))

for(const item of items) {
    map.get(item.type).doSomething(item)
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا