برنامه نویسی

رمزگشایی روش های آرایه – انجمن DEV

به نوعی، به نوعی، مردم فکر می کنند for درک و درک حلقه ها آسان تر است… من اینجا هستم تا آن را تغییر دهم.

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

مبانی

اکثر روش ها، به استثنای موارد، دارای امضای یکسان هستند.

بیایید با آن مقایسه کنیم for حلقه ها:

const array = ['a', 'b', 'c'];

// the classic `for` loop you can have better
// control over the indexed you're using
for (let index = 0; index < array.length; index++) {
  const element = array[index];
  console.log(element); // a, b, c
}

// the `for in` gives the index
for (const index in array) {
  const element = array[index];
  console.log(element); // a, b, c
}

// the `for of` gives the element
for (const element of array) {
  console.log(element); // a, b, c
}
وارد حالت تمام صفحه شوید

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

  • عنصر – معمولاً این تنها چیزی است که واقعاً نیاز دارید
  • index – کاربردهایی برای استفاده از ایندکس وجود دارد
  • آرایه – هنگام زنجیر کردن متدها، این به شما امکان می دهد از مقادیر فعلی در مرحله ای که در آن هستید استفاده کنید.

دو چیز را باید به خاطر بسپارید:

  • از بهترین روش برای کاری که انجام می دهید استفاده کنید

اگر نیازی به بازگرداندن چیزی ندارید، از a map این بازگشت باعث می شود فکر کنم شما فراموش کرده اید چیزی را برگردانید.

به همین ترتیب، راه‌های دوربرگردان زیادی وجود دارد که وضعیت فعلی زبان راه‌های بهتری برای انجام آن‌ها دارد، مانند استفاده از findIndex !== -1 وقتی یک some همین کار را خواهد کرد.

تا زمانی که چیزی که برمی گردانید آرایه دیگری باشد، می توانید کاری انجام دهید و آن را به مرحله بعدی منتقل کنید.

گاهی اوقات این منطقی است، اما گاهی اوقات، ممکن است بخواهید آنها را به متغیرهای توصیفی اختصاص دهید.

برای هر

“برای هر عنصر” در آرایه، کاری انجام می دهد و چیزی بر نمی گرداند.

['a', 'b', 'c'].forEach((element) => {
  // console.log doesn't return anything
  // so it's perfect for the forEach
  console.log(element); // a, b, c
})
وارد حالت تمام صفحه شوید

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

شما زمانی از آن استفاده می کنید که فقط نیاز به انجام کاری دارید و چیزی را پس نمی دهید: سیاهه ها، نان تست…

درک و استفاده از آن آسان است، اما از آنجایی که چیزی را بر نمی گرداند، واقعاً کاربردهای زیادی وجود ندارد. (روش های بهتری برای هر چیزی که فکر می کنید وجود دارد)

نقشه

فرزند پوستر متدهای آرایه!

برای هر عنصر در آرایه، یک مقدار برمی گرداند.

(توجه: حتی اگر برنگردید باز می گردد undefined)

// not adding {} in the arrow function, means it returns implicitly
[1, 2, 3].map(element => element * 2); // result array is [2, 4, 6]

[1, 2, 3].map(element => {
  if(element % 2 !== 0) { // remainder of the division by 2 not equal to zero 
    return element * 2;
  }
  // no "else" returns
}) // resulting array [2, undefined, 6]
وارد حالت تمام صفحه شوید

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

از آنجایی که آرایه ای با همان اندازه را برمی گرداند، می توان از آن برای چندین چیز استفاده کرد و زنجیره سازی را آسان می کند.

كاهش دادن

آفت مردمی که روش‌ها را یاد می‌گیرند… اما واقعاً آنقدرها هم پیچیده نیست.

برای هر عنصر در آرایه، “یک” چیز را برمی گرداند (که می تواند هر چیزی باشد).

به صورت اختیاری، می توانید یک مقدار شروع داشته باشید.

// classical use case
[1, 2, 3].reduce((accumulator, element) => accumulator + element, 0); // returns 6

// classical mistake nr 1: not returning anything
[1, 2, 3].reduce((accumulator, element) => {
  console.log(accumulator); // 0 (initial value), undefined, undefined (undefined because you didn't return)
  console.log(element); // 1, 2, 3
  accumulator + element; // this would be 1 (0 + 1), then NaN, NaN (number + undefined/NaN)
  // always remember to return something, even if only the accumulator
}, 0);

// (possible) mistake: not having an initial value
// no initial value means the first element is the initial value
[1, 2, 3].reduce((accumulator, element)=> accumulator + element); // retuns 6
[].reduce((accumulator, element)=> accumulator + element); // throws because empty array with no initial value

// things start to be different for more complex use cases
[1, 2, 3].reduce((accumulator, element)=>{
  if (element % 2 === 0) {
    accumulator.even.push(element);
  } else {
    accumulator.odd.push(element);
  }

  return accumulator;
// below I'm using JSDoc to type the initial value
// because using JS doesn't mean not using types ;]
}, /** @type {{ even: number[], odd: number[] }} */ ({ even: [], odd: []}));
// this returns: { even: [ 2 ], odd: [ 1, 3 ] }
// Not using an initial value will break this in multiple ways.

// this is another way to write the same thing
[1, 2, 3].reduce((accumulator, element)=>{
  if (element % 2 === 0) {
    return {
      ...accumulator,
      even: accumulator.even.concat(element),
    }
  }

  return {
    ...accumulator,
    odd: accumulator.odd.concat(element),
  }
}, /** @type {{ even: number[], odd: number[] }} */({ even: [], odd: []}));
// the important thing to remember is to always return something

// the "one" thing it returns can be anything:
[1, 2, 3].reduce((accumulator, element) => {
  if (element % 2 === 0) {
    accumulator[1] += element;
  } else {
    accumulator[0] += element;
  }
  return accumulator;
}, /** @type {[number, number]} [*/([0, 0]));
// this returns [4, 2]
// and would again have multiple problems without an initial value
وارد حالت تمام صفحه شوید

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

اگر می‌خواهید یک یا چند متغیر را در خارج نمونه‌سازی کنید، از a استفاده کنید for حلقه یا حتی یک forEach و آن را جهش دهید، سپس یک مورد استفاده برای آن است reduce.

همیشه یک چیز را برمی گرداند، و همانطور که می بینید می تواند هر چیزی باشد: عدد، رشته، آرایه، شی…

در حالی که، شما اساساً می توانید هر کاری را با آن انجام دهید reduce، بررسی کنید که آیا روش دیگری وجود ندارد که این مورد را بهتر پوشش دهد.

یک نیز وجود دارد reduceRight این همان چیزی است، اما از آخرین عنصر شروع می شود.

فیلتر کنید

برای هر عنصر در آرایه، آرایه ای را برمی گرداند که می تواند اندازه کوچکتری داشته باشد.

در حالی که reduce یک چیز را برمی گرداند، filter همیشه آرایه ای را برمی گرداند که می تواند از خالی به همان اندازه ورودی باشد.

[1, 2, 3].filter(element => element % 2 !== 0); // returns [1, 3]
[1, 2, 3].filter(element => element % 5 === 0); // return [0]

// one common use case: remove falsy values
[1, 2, 3].map(element => {
  if (element % 2 !== 0) {
    return element;
  }
}) // at this point you would have: [1, undefined, 3]
  .filter(Boolean); // after this return [1, 3]
وارد حالت تمام صفحه شوید

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

اگر می خواهید مقادیر را از یک آرایه حذف کنید، filter روشی است که شما می خواهید

و برای کسانی که نمی دانستند: filter(Boolean) روشی زیبا برای حذف مقادیر نادرست است.

باید مراقب باشید که مقادیر نادرست مانند را حذف کند '' (رشته خالی) و 0 (صفر).

مسطح و مسطح نقشه

صاف کردن یک آرایه چیزی نیست که هر روز از آن استفاده کنید، اما مطمئناً در بسیاری از موارد مفید است. اساساً به flat حذف ابعاد از یک آرایه است.

اگر ماتریس 2×2 دارید: [[1, 1], [1, 1]] و شما آن را صاف می کنید، در نهایت با یک آرایه 4 آیتم ساده مواجه می شوید: [1, 1, 1, 1].

[1, 2, 3].map(element => {
  return [[[element]]]; // sometimes you return values/tuples
  // depending on what you really wanted to return, you just need to flat it
}) // here would return [[[[1]]],[[[2]]],[[[3]]]]
  .flat(1) // returns [[[1]],[[2]],[[3]]]
  .flat(2); // returns [1, 2, 3]

[1, 2, 3].map(element => {
  return [[[element]]];
}) // here would return [[[[1]]],[[[2]]],[[[3]]]]
  .flat(Infinity); // returns [1, 2, 3]
  // flatting to infinity means it will remove all dimensions
وارد حالت تمام صفحه شوید

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

شما تماس بگیرید flat از یک آرایه و عددی را می گیرد که تعداد ابعاد را از آن جدا می کنید. اگر می خواهید یک آرایه ساده به عنوان نتیجه داشته باشید، مهم نیست که آرایه چقدر ابعاد دارد، از آن استفاده کنید flat(Infinity) همانطور که این کار را انجام خواهد داد.

[1, 2, 3].flatMap(element => {
  return [element * 2]; // returns [2], [4], [6]
}); // returns [2, 4, 6] because it flattened

[1, 2, 3].flatMap(element => {
  if (element % 2 === 0) {
    return element * 2; // return 4
  }
  // without returning anything, it would result in [undefined, 4, undefined]
  // while flatMap doesn't remove falsy values
  // a flattened empty array disappear
  return [];
}); // returns [4]
وارد حالت تمام صفحه شوید

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

flatMap اساسا یک است map به دنبال flat(1).

TIL: می توانید استفاده کنید flatMap و برگشت [] برای مقادیر نادرست فقط مقادیر را برمی گرداند

برخی و هر

آنها موارد سرگرم کننده ای هستند که پس از یادگیری در مورد شما موارد استفاده را در همه جا پیدا خواهید کرد!

معمولاً مورد استفاده به صورت زیر است: filter(/* for something */).length /* (not) equal to something */ یا Boolean(find(/* something (not) equal */)) .

برای هر عنصر در آرایه، some اگر حداقل یکی از گزاره عبور کند true برمی گرداند، every اگر همه از آن عبور کنند

[1, 2, 3].some(element => element % 2 === 0); // true
[1, 2, 3].every(element => element % 2 === 0); // false
وارد حالت تمام صفحه شوید

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

یک چیز جالب این است که هر دو زودتر برمی گردند، some در اول truthy ارزش بازگشتی و every در اول falsy مقدار بازگشتی

هنگامی که تنها چیزی که نیاز دارید یک بولی از اگر چیزی وجود دارد یا نه است، از هر کدام استفاده کنید some یا every.

پیدا کردن و پیدا کردن ایندکس

find اولین عنصری را که از گزاره یا عبور می کند برمی گرداند undefined در غیر این صورت، findIndex ایندکس عنصر یا را برمی گرداند -1 در غیر این صورت.

هر دو از فهرست شروع به جستجو می کنند 0، اما اگر آخرین مورد را می خواهید، از تغییرات “آخرین” استفاده کنید.

// returns the element:
[1, 2, 3].find(element => element % 2 !== 0); // 1
[1, 2, 3].findLast(element => element % 2 !== 0); // 3

// return the index:
[1, 2, 3].findIndex(element => element % 2 !== 0); // 0
[1, 2, 3].findLastIndex(element => element % 2 !== 0); // 2
وارد حالت تمام صفحه شوید

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

شامل می شود

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

[1, 2, 3].includes(1); // true
[1, 2, 3].includes('1'); // false
وارد حالت تمام صفحه شوید

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

به احتمال زیاد، ما می توانیم در اینجا وارد کنیم indexOf و lastIndexOf هر دو یک مقدار را بررسی می کنند، اما شاخص یا را برمی گرداند -1 در غیر این صورت.

[1, 0, 1].indexOf(1); // 0
[1, 0, 1].indexOf('1'); // -1

[1, 0, 1].lastIndexOf(1); // 2
[1, 0, 1].lastIndexOf('1'); // -1
وارد حالت تمام صفحه شوید

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

مورد استفاده برای includes در این میان معمولاً در حال جستجوی آرایه ای از مقادیر اولیه (رشته، عدد، نمادها…) است. some و every برای چیزهای پیچیده تر از اینکه مقدار وجود دارد یا نه یا برای اشیا استفاده می شود.

آخرین اظهارات

اسناد MDN به همان اندازه که می آیند خوب هستند. ممکن است ندانید که همه آنها وجود دارند، اما زمانی که متوجه شوید آنها کاملاً ساده هستند.

سپس، ممکن است برخی از افراد بدانند که روش ها وجود دارد، اما نحوه به کارگیری آنها را ندانند. بنابراین، اگر می خواهید، نمونه هایی را بفرستید که نمی دانید چگونه روش ها را اعمال کنید و من می توانم گزینه ها را اصلاح کنم.

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

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

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

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