JS數(shù)組代碼片段

all

函數(shù)封裝了every函數(shù),判斷條件默認為元素默認轉(zhuǎn)為boolean值,如果都為true,則返回true。否則,返回false。

const all = (arr, fn = Boolean) => arr.every(fn);

all([4, 2, 3], x => x > 1); // true
all([1, 2, 3]); // true

allEqual

檢查數(shù)組中的所有元素是否與第一個元素相同。

const allEqual = arr => arr.every(val => val === arr[0]);

allEqual([1, 2, 3, 4, 5, 6]); // false
allEqual([1, 1, 1, 1]); // true

any

檢查數(shù)組中的所有元素是否基于fn返回true。只要數(shù)組元素有一個轉(zhuǎn)為true,則返回true。省略第二個參數(shù)fn,將布爾值用作默認值。

const any = (arr, fn = Boolean) => arr.some(fn);

any([0, 1, 2, 0], x => x >= 2); // true
any([0, 0, 1, 0]); // true

arrayMax

返回數(shù)組中的最大值。
Math.max()返回參數(shù)中最大的值。如果沒有參數(shù),返回-Infinity。如果有某個參數(shù)為NaN,或是不能轉(zhuǎn)換成數(shù)字的非數(shù)字值,則返回NaN。

const arrayMax = arr => Math.max(...arr);
// arrayMax([10, 1, 5]) -> 10

arrayMin

返回數(shù)組中的最小值。

const arrayMin = arr => Math.min(...arr);
// arrayMin([10, 1, 5]) -> 1

chunk

把一個數(shù)組分塊成指定大小的小數(shù)組。
使用Array.from()創(chuàng)建一個新的數(shù)組,它的長度與將要生成的chunk(塊) 數(shù)量相匹配。 使用Array.slice()將新數(shù)組的每個元素映射到長度為sizechunk中。 如果原始數(shù)組不能均勻分割,最后的chunk將包含剩余的元素。

const chunk = (arr, size) =>
  Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
    arr.slice(i * size, i * size + size)
  );

chunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]

compact

過濾掉數(shù)組中所有假值元素。
使用Array.filter()過濾掉數(shù)組中所有假值元素(false, null, 0, "", undefined, and NaN)。

const compact = arr => arr.filter(Boolean);

compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]); // [ 1, 2, 3, 'a', 's', 34 ]

countBy

根據(jù)給定的函數(shù)對數(shù)組的元素進行分組,并返回每個分組中元素的數(shù)量。
使用Array.map()將數(shù)組的值映射到函數(shù)或?qū)傩悦Q。 使用Array.reduce()創(chuàng)建一個對象,其中的鍵是從映射的結(jié)果中產(chǎn)生的。

const countBy = (arr, fn) =>
  arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => {
    acc[val] = (acc[val] || 0) + 1;
    return acc;
  }, {});

countBy([6.1, 4.2, 6.3], Math.floor); // {4: 1, 6: 2}
countBy(['one', 'two', 'three'], 'length'); // {3: 2, 5: 1}

countOccurrences

計數(shù)數(shù)組中某個值的出現(xiàn)次數(shù)。
每次遇到數(shù)組中的指定值時,使用Array.reduce()來遞增計數(shù)器。

const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);

countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3

difference

返回兩個數(shù)組之間的差異。
根據(jù)數(shù)組b創(chuàng)建一個Set對象,然后在數(shù)組a上使用Array.filter()方法,過濾出數(shù)組b中不包含的值。

const difference = (a, b) => {
  const s = new Set(b);
  return a.filter(x => !s.has(x));
};

difference([1, 2, 3], [1, 2, 4]); // [3]

differenceWith

過濾出數(shù)組中比較函數(shù)不返回true的所有值。 類似于difference,除了接受一個comparator(比較函數(shù))。
使用Array.filter()Array.findIndex()來查找合適的值。

const differenceWith = (arr, val, comp) => arr.filter(a => val.findIndex(b => comp(a, b)) === -1);

differenceWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0], (a, b) => Math.round(a) === Math.round(b)); // [1, 1.2]

drop

從數(shù)組開頭刪除n位元素。

const drop = (arr, n = 1) => arr.slice(n);

drop([1, 2, 3]); // [2,3]
drop([1, 2, 3], 2); // [3]
drop([1, 2, 3], 42); // []

dropRight

返回從右開始刪除n個元素的新數(shù)組。
檢查n是否小于給定數(shù)組的長度,并且使用Array.slice()來從右開始刪除指定數(shù)量的元素。

const dropRight = (arr, n = 1) => arr.slice(0, -n);

dropRight([1, 2, 3]); // [1,2]
dropRight([1, 2, 3], 2); // [1]
dropRight([1, 2, 3], 42); // []

dropWhile

從數(shù)組左邊開始刪除元素,判斷條件為func。一直刪除到數(shù)組左邊直至遇到能讓func變?yōu)?code>true的元素。

const dropWhile = (arr, func) => {
  while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1);
  return arr;
};

dropRightWhile

從數(shù)組右邊開始刪除元素,判斷條件為func。一直刪除到數(shù)組右邊直至遇到能讓func變?yōu)?code>true的元素。

const dropRightWhile = (arr, func) => {
  let rightIndex = arr.length;
  while (rightIndex-- && !func(arr[rightIndex]));
  return arr.slice(0, rightIndex + 1);
};

dropRightWhile([1, 2, 3, 4], n => n < 3); // [1, 2]

everyNth

返回數(shù)組中的每個第n個元素。
使用Array.filter()創(chuàng)建一個包含給定數(shù)組的每個第n個元素的新數(shù)組。

const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1);

everyNth([1, 2, 3, 4, 5, 6], 2); // [ 2, 4, 6 ]

filterFalsy

去除數(shù)組中能轉(zhuǎn)換為false的元素。

const filterFalsy = arr => arr.filter(Boolean);

filterFalsy(['', true, {}, false, 'sample', 1, 0]); // [true, {}, 'sample', 1]

filterNonUnique

去掉數(shù)組中的非唯一值。

const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));

filterNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1, 3, 5]

filterNonUniqueBy

擴展了filterNonUnique方法,通過方法fn進行判斷。fn四個參數(shù)是比較兩個元素的值和索引(方便fn方法的擴展)

(i === j) === fn(v, x, i, j)

注意arr.every(),當數(shù)組內(nèi)所有索引和值比較過,都為true,那個元素才是獨一無二的。

const filterNonUniqueBy = (arr, fn) =>
  arr.filter((v, i) => arr.every((x, j) => (i === j) === fn(v, x, i, j)));

filterNonUniqueBy(
  [
    { id: 0, value: 'a' },
    { id: 1, value: 'b' },
    { id: 2, value: 'c' },
    { id: 1, value: 'd' },
    { id: 0, value: 'e' }
  ],
  (a, b) => a.id == b.id
); // [ { id: 2, value: 'c' } ]

findLast

尋找數(shù)組最后一個能滿足fn的元素。

const findLast = (arr, fn) => arr.filter(fn).pop();

findLast([1, 2, 3, 4], n => n % 2 === 1); // 3

findLastIndex

尋找數(shù)組最后一個能滿足fn的元素的索引。

const findLastIndex = (arr, fn) =>
  arr
    .map((val, i) => [i, val])
    .filter(([i, val]) => fn(val, i, arr))
    .pop()[0];

findLastIndex([1, 2, 3, 4], n => n % 2 === 1); // 2 (index of the value 3)

flatten

根據(jù)指定的depth平鋪數(shù)組。
每次遞歸,使depth減1 。使用Array.reduce()Array.concat()來合并元素或數(shù)組。默認情況下, depth等于1時停遞歸。省略第二個參數(shù)depth,只能平鋪1層的深度 (單層平鋪)。

const flatten = (arr, depth = 1) =>
  arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v), []);

flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]

ES6方法:

[1, 2, [3, [4, 5]]].flat() // [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5]
[1, [2, [3]]].flat(Infinity) // [1, 2, 3]

deepFlatten

深度平鋪數(shù)組。
使用遞歸。 通過空數(shù)組([]) 使用Array.concat(),結(jié)合展開運算符(...) 來平鋪數(shù)組。 遞歸平鋪每個數(shù)組元素。

const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));

deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]

其他方法:

const deepFlatten = (arr) => {
  while(arr.some(item => Array.isArray(item))) {
    arr = [].contact(...arr);
  }
  return arr;
}
deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]

forEachRight

從數(shù)組的最后一個元素開始,為每個數(shù)組元素執(zhí)行一次提供的函數(shù)。
使用Array.slice(0)克隆給定的數(shù)組,Array.reverse()反轉(zhuǎn)數(shù)組,Array.forEach()遍歷這個反向數(shù)組。

const forEachRight = (arr, callback) =>
  arr
    .slice(0)
    .reverse()
    .forEach(callback);

forEachRight([1, 2, 3, 4], val => console.log(val)); // '4', '3', '2', '1'

groupBy

根據(jù)給定的函數(shù)對數(shù)組元素進行分組。
使用Array.map()將數(shù)組的值映射到函數(shù)或?qū)傩悦Q。使用Array.reduce()來創(chuàng)建一個對象,其中的key是從映射結(jié)果中產(chǎn)生。

const groupBy = (arr, fn) =>
  arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val, i) => {
    acc[val] = (acc[val] || []).concat(arr[i]);
    return acc;
  }, {});

groupBy([6.1, 4.2, 6.3], Math.floor); // {4: [4.2], 6: [6.1, 6.3]}
groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']}

head

獲取數(shù)組的第一個元素。
使用arr[0]返回傳遞數(shù)組的第一個元素。

const head = arr => arr[0];

head([1, 2, 3]); // 1

indexOfAll

返回數(shù)組中所有val的索引。 如果val從不出現(xiàn),則返回[]。
使用Array.forEach()循環(huán)元素和Array.push()來存儲匹配元素的索引。返回索引數(shù)組。

const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);

indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []

initial

返回一個數(shù)組中除了最后一個元素以外的所有元素。
使用arr.slice(0,-1)返回排除了最后一個元素的數(shù)組。

const initial = arr => arr.slice(0, -1);

initial([1, 2, 3]); // [1,2]

initialize2DArray

初始化一個給定行數(shù)和列數(shù),及值的二維數(shù)組。
使用Array.map()生成h行,其中每個行都是一個長度為w的新數(shù)組。 如果未提供值val,則默認為null

const initialize2DArray = (w, h, val = null) =>
  Array.from({ length: h }).map(() => Array.from({ length: w }).fill(val));

initialize2DArray(2, 2, 0); // [[0,0], [0,0]]

initializeArrayWithRange

初始化一個數(shù)組,該數(shù)組包含指定范圍內(nèi)的數(shù)字,包括startend,數(shù)字間隔為step。
使用Array.from(Math.ceil((end+1-start)/step))創(chuàng)建一個所需長度的數(shù)組(元素的數(shù)量等于 (end-start)/step或者(end+1-start)/step包括end), 用Array.map()填充在這個范圍內(nèi)要求的值。你可以省略start來使用默認值0。 您可以省略step使用默認值1 。

const initializeArrayWithRange = (end, start = 0, step = 1) =>
  Array.from({ length: Math.ceil((end - start + 1) / step) }, (v, i) => i * step + start);

initializeArrayWithRange(5); // [0,1,2,3,4,5]
initializeArrayWithRange(7, 3); // [3,4,5,6,7]
initializeArrayWithRange(9, 0, 2); // [0,2,4,6,8]

initializeArrayWithValues

使用指定的值初始化和填充數(shù)組。
使用Array(n)創(chuàng)建所需長度的數(shù)組,使用fill(v)以填充所需的值。你可以忽略val,使用默認值0。

const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);

initializeArrayWithValues(5, 2); // [2, 2, 2, 2, 2]

intersection

返回兩個數(shù)組中都存在的元素列表。
根據(jù)數(shù)組 b創(chuàng)建一個Set對象,然后在數(shù)組a上使用Array.filter()方法,只保留數(shù)組b中也包含的值。

const intersection = (a, b) => {
  const s = new Set(b);
  return a.filter(x => s.has(x));
};

intersection([1, 2, 3], [4, 3, 2]); // [2, 3]

join

將數(shù)組的所有元素拼接成一個字符串并返回此字符串。 使用分隔符和結(jié)束分隔符。
使用Array.reduce()將元素拼接成一個字符串。 省略第二個參數(shù)separator,則默認使用分隔符,。 省略第三個參數(shù)end,默認使用與separator相同的值。

const join = (arr, separator = ',', end = separator) =>
  arr.reduce(
    (acc, val, i) =>
      i === arr.length - 2
        ? acc + val + end
        : i === arr.length - 1
          ? acc + val
          : acc + val + separator,
    ''
  );

join(['pen', 'pineapple', 'apple', 'pen'], ',', '&'); // "pen,pineapple,apple&pen"
join(['pen', 'pineapple', 'apple', 'pen'], ','); // "pen,pineapple,apple,pen"
join(['pen', 'pineapple', 'apple', 'pen']); // "pen,pineapple,apple,pen"

last

返回數(shù)組中的最后一個元素。
使用arr.length - 1來計算給定數(shù)組的最后一個元素的索引并返回。

const last = arr => arr[arr.length - 1];

last([1, 2, 3]); // 3

longestItem

獲取任何數(shù)量的可迭代對象或具有length屬性的對象,并返回最長的一個。
使用Array.sort()length對所有參數(shù)進行排序,返回第一個(最長)元素。

const longestItem = (...vals) => vals.reduce((a, x) => (x.length > a.length ? x : a));

longestItem('this', 'is', 'a', 'testcase'); // 'testcase'
longestItem(...['a', 'ab', 'abc']); // 'abc'
longestItem(...['a', 'ab', 'abc'], 'abcd'); // 'abcd'
longestItem([1, 2, 3], [1, 2], [1, 2, 3, 4, 5]); // [1, 2, 3, 4, 5]
longestItem([1, 2, 3], 'foobar'); // 'foobar'

mapObject

使用一個函數(shù)將數(shù)組的值映射到對象,其鍵值對中,原始值作為鍵,映射值作為值。
使用一個匿名的內(nèi)部函數(shù)作用域來聲明一個undefined的內(nèi)存空間,使用閉包來存儲返回值。 使用一個新的Array來存儲帶有函數(shù)映射的數(shù)組和一個逗號運算符來返回第二個步驟,而不需要從一個上下文移動到另一個上下文(由于閉包和操作順序)。

const mapObject = (arr, fn) =>
  (a => (
    (a = [arr, arr.map(fn)]), a[0].reduce((acc, val, ind) => ((acc[val] = a[1][ind]), acc), {})
  ))();

const squareIt = arr => mapObject(arr, a => a * a);
squareIt([1, 2, 3]); // { 1: 1, 2: 4, 3: 9 }

maxN

從提供的數(shù)組中返回n個最大元素。如果n大于或等于提供的數(shù)組長度,則返回原數(shù)組(按降序排列)。
結(jié)合使用Array.sort()與展開操作符(...) ,創(chuàng)建一個數(shù)組的淺克隆,并按降序排列。使用Array.slice()以獲得指定的元素個數(shù)。 忽略第二個參數(shù)n,默認獲取單個元素(以數(shù)組的形式)。

const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n);

maxN([1, 2, 3]); // [3]
maxN([1, 2, 3], 2); // [3,2]

minN

從提供的數(shù)組中返回n個最小元素。如果n大于或等于提供的數(shù)組長度,則返回原數(shù)組(按降序排列)。
結(jié)合使用Array.sort()與展開操作符(...) ,創(chuàng)建一個數(shù)組的淺克隆,并按降序排列。使用Array.slice()以獲得指定的元素個數(shù)。 忽略第二個參數(shù)n,默認獲取單個元素(以數(shù)組的形式)。

const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);

minN([1, 2, 3]); // [1]
minN([1, 2, 3], 2); // [1,2]

nthElement

返回數(shù)組的第n個元素。
使用Array.slice()獲取數(shù)組的第n個元素。如果索引超出范圍,則返回[]。省略第二個參數(shù)n,將得到數(shù)組的第一個元素。

const nthElement = (arr, n = 0) => (n === -1 ? arr.slice(n) : arr.slice(n, n + 1))[0];

nthElement(['a', 'b', 'c'], 1); // 'b'
nthElement(['a', 'b', 'b'], -3); // 'a'

partition

根據(jù)所提供的函數(shù)對每個元素進行迭代,將這些元素分成兩個數(shù)組。
使用Array.reduce()創(chuàng)建兩個數(shù)組的數(shù)組。 使用Array.push()fn返回為true的元素添加到第一個數(shù)組,而fn返回false的元素到第二個元素。

const partition = (arr, fn) =>
  arr.reduce(
    (acc, val, i, arr) => {
      acc[fn(val, i, arr) ? 0 : 1].push(val);
      return acc;
    },
    [[], []]
  );

const users = [{ user: 'barney', age: 36, active: false }, { user: 'fred', age: 40, active: true }];
partition(users, o => o.active); 
// [[{ 'user': 'fred', 'age': 40, 'active': true }],[{ 'user': 'barney', 'age': 36, 'active': false }]]

pull

改變原始數(shù)組,過濾掉指定的值。
使用Array.filter()Array.includes()來剔除指定的值。使用Array.length = 0將數(shù)組中的長度重置為零,并且通過Array.push()只使用pulled值重新填充數(shù)組。

const pull = (arr, ...args) => {
  let argState = Array.isArray(args[0]) ? args[0] : args;
  let pulled = arr.filter((v, i) => !argState.includes(v));
  arr.length = 0;
  pulled.forEach(v => arr.push(v));
};

let myArray = ['a', 'b', 'c', 'a', 'b', 'c'];
pull(myArray, 'a', 'c'); // myArray = [ 'b', 'b' ]

pullAtIndex

改變原始數(shù)組,過濾掉指定索引的值。
使用Array.filter()Array.includes()來剔除指定的值。使用Array.length = 0將數(shù)組中的長度重置為零,并且通過Array.push()只使用pulled值重新填充數(shù)組。使用Array.push()來跟蹤pulled值。

const pullAtIndex = (arr, pullArr) => {
  let removed = [];
  let pulled = arr
    .map((v, i) => (pullArr.includes(i) ? removed.push(v) : v))
    .filter((v, i) => !pullArr.includes(i));
  arr.length = 0;
  pulled.forEach(v => arr.push(v));
  return removed;
};

let myArray = ['a', 'b', 'c', 'd'];
let pulled = pullAtIndex(myArray, [1, 3]); // myArray = [ 'a', 'c' ] , pulled = [ 'b', 'd' ]

pullAtValue

改變原始數(shù)組,過濾出指定的值。 返回刪除的元素。
使用Array.filter()Array.includes()來剔除指定的值。使用Array.length = 0將數(shù)組中的長度重置為零, 并且通過Array.push()只使用pulled值重新填充數(shù)組。使用Array.push()來跟蹤pulled值。

const pullAtValue = (arr, pullArr) => {
  let removed = [],
    pushToRemove = arr.forEach((v, i) => (pullArr.includes(v) ? removed.push(v) : v)),
    mutateTo = arr.filter((v, i) => !pullArr.includes(v));
  arr.length = 0;
  mutateTo.forEach(v => arr.push(v));
  return removed;
};

let myArray = ['a', 'b', 'c', 'd'];
let pulled = pullAtValue(myArray, ['b', 'd']); // myArray = [ 'a', 'c' ] , pulled = [ 'b', 'd' ]

reducedFilter

根據(jù)條件過濾一個對象數(shù)組,同時過濾掉未指定的鍵(key)。
使用Array.filter()根據(jù)斷言fn過濾數(shù)組,以便返回條件為真值(truthy)的對象。在過濾出來的數(shù)組上,使用Array.map()Array.reduce()返回新的對象來過濾掉keys參數(shù)中未提供的鍵。

const reducedFilter = (data, keys, fn) =>
  data.filter(fn).map(el =>
    keys.reduce((acc, key) => {
      acc[key] = el[key];
      return acc;
    }, {})
  );

const data = [
  {
    id: 1,
    name: 'john',
    age: 24
  },
  {
    id: 2,
    name: 'mike',
    age: 50
  }
];

reducedFilter(data, ['id', 'name'], item => item.age > 24); // [{ id: 2, name: 'mike'}]

remove

從數(shù)組中移除給定函數(shù)返回false的元素。
使用Array.filter()Array.reduce()來查找返回真值的數(shù)組元素,使用Array.splice()來移除元素。func有三個參數(shù)(value, index, array)

const remove = (arr, func) =>
  Array.isArray(arr)
    ? arr.filter(func).reduce((acc, val) => {
      arr.splice(arr.indexOf(val), 1);
      return acc.concat(val);
    }, [])
    : [];

remove([1, 2, 3, 4], n => n % 2 === 0); // [2, 4]

sample

從數(shù)組中隨機返回一個元素。
使用Math.random()生成一個隨機數(shù),乘以length,并使用Math.floor()舍去小數(shù)獲得到最接近的整數(shù)。這個方法也適用于字符串。

const sample = arr => arr[Math.floor(Math.random() * arr.length)];

sample([3, 7, 9, 11]); // 9

sampleSize

array中獲取n個唯一鍵隨機元素。
使用Fisher-Yates(洗牌算法)對數(shù)組進行打亂。使用Array.slice()獲取第一個n元素。 省略第二個參數(shù),n從數(shù)組中隨機取得1個元素。

const sampleSize = ([...arr], n = 1) => {
  let m = arr.length;
  while (m) {
    const i = Math.floor(Math.random() * m--);
    [arr[m], arr[i]] = [arr[i], arr[m]];
  }
  return arr.slice(0, n);
};

sampleSize([1, 2, 3], 2); // [3,1]
sampleSize([1, 2, 3], 4); // [2,3,1]

shank

array.prototype.splice()具有相同的功能,但返回新數(shù)組而不是改變原始數(shù)組。

const shank = (arr, index = 0, delCount = 0, ...elements) =>
  arr
    .slice(0, index)
    .concat(elements)
    .concat(arr.slice(index + delCount));

const names = ['alpha', 'bravo', 'charlie'];
const namesAndDelta = shank(names, 1, 0, 'delta'); // [ 'alpha', 'delta', 'bravo', 'charlie' ]
const namesNoBravo = shank(names, 1, 1); // [ 'alpha', 'charlie' ]
console.log(names); // ['alpha', 'bravo', 'charlie']

shuffle

隨機排列指定數(shù)組的值,返回一個新的數(shù)組。
使用Fisher-Yates算法對數(shù)組元素進行重新排序。

const shuffle = ([...arr]) => {
  let m = arr.length;
  while (m) {
    const i = Math.floor(Math.random() * m--);
    [arr[m], arr[i]] = [arr[i], arr[m]];
  }
  return arr;
};

const foo = [1, 2, 3];
shuffle(foo); // [2, 3, 1], foo = [1, 2, 3]

similarity

返回存在于兩個數(shù)組中的元素數(shù)組。
使用Array.filter()移除不在values中的值,使用Array.includes()確定。

const similarity = (arr, values) => arr.filter(v => values.includes(v));

similarity([1, 2, 3], [1, 2, 4]); // [1, 2]

symmetricDifference

返回兩個數(shù)組之間的差集。
根據(jù)每個數(shù)組創(chuàng)建一個Set,然后在每個數(shù)組上使用Array.filter(),只保留另一個數(shù)組不包含的值。

const symmetricDifference = (a, b) => {
  const sA = new Set(a),
    sB = new Set(b);
  return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))];
};

symmetricDifference([1, 2, 3], [1, 2, 4]); // [3, 4]
symmetricDifference([1, 2, 2], [1, 3, 1]); // [2, 2, 3]

symmetricDifferenceBy

將提供的函數(shù)應用于兩個數(shù)組的每個數(shù)組元素后,返回兩個數(shù)組之間的差集。
通過對每個數(shù)組的元素應用fn創(chuàng)建一個集合,然后對每個元素使用array.prototype.filter()來只保留不包含在另一個數(shù)組中的值。

const symmetricDifferenceBy = (a, b, fn) => {
  const sA = new Set(a.map(v => fn(v))),
    sB = new Set(b.map(v => fn(v)));
  return [...a.filter(x => !sB.has(fn(x))), ...b.filter(x => !sA.has(fn(x)))];
};

symmetricDifferenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [ 1.2, 3.4 ]

tail

返回剔除第一個元素后的數(shù)組。
如果數(shù)組的length大于1,則返回arr.slice(1),否則返回整個數(shù)組。

const tail = arr => (arr.length > 1 ? arr.slice(1) : arr);

tail([1, 2, 3]); // [2,3]
tail([1]); // [1]

take

從一個給定的數(shù)組中創(chuàng)建一個前n個元素的數(shù)組。
使用Array.slice()創(chuàng)建一個數(shù)組包含第一個元素開始,到n個元素結(jié)束的數(shù)組。

const take = (arr, n = 1) => arr.slice(0, n);

take([1, 2, 3], 5); // [1, 2, 3]
take([1, 2, 3], 0); // []

takeRight

從一個給定的數(shù)組中創(chuàng)建一個后n個元素的數(shù)組。
使用Array.slice()來創(chuàng)建一個從第n個元素開始至末尾的數(shù)組。

const takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length);

takeRight([1, 2, 3], 2); // [ 2, 3 ]
takeRight([1, 2, 3]); // [3]

takeWhile

移除數(shù)組中的元素,直到傳遞的函數(shù)返回true。返回刪除的元素。
循環(huán)數(shù)組,使用for…of循環(huán)array.prototype.entries(),直到函數(shù)返回的值為true。使用array.prototype.slice()返回刪除的元素。

const takeWhile = (arr, func) => {
  for (const [i, val] of arr.entries()) if (func(val)) return arr.slice(0, i);
  return arr;
};

takeWhile([1, 2, 3, 4], n => n >= 3); // [1, 2]

takeRightWhile

從數(shù)組末尾移除元素,直到傳遞的函數(shù)返回true。返回刪除的元素。
使用array.prototype.reducceright()循環(huán)數(shù)組,并在函數(shù)返回錯誤值時累積元素。

const takeRightWhile = (arr, func) =>
  arr.reduceRight((acc, el) => (func(el) ? acc : [el, ...acc]), []);

takeRightWhile([1, 2, 3, 4], n => n < 3); // [3, 4]

union

返回兩個數(shù)組中任何一個中存在的每個元素一次。
創(chuàng)建一個包含A和B所有值的集合,并轉(zhuǎn)換為數(shù)組。

const union = (a, b) => Array.from(new Set([...a, ...b]));

union([1, 2, 3], [4, 3, 2]); // [1,2,3,4]

unionBy

將提供的函數(shù)應用于兩個數(shù)組的每個數(shù)組元素之后,返回兩個數(shù)組中任何一個數(shù)組中存在的每個元素一次。

const unionBy = (a, b, fn) => {
  const s = new Set(a.map(fn));
  return Array.from(new Set([...a, ...b.filter(x => !s.has(fn(x)))]));
};

unionBy([2.1], [1.2, 2.3], Math.floor); // [2.1, 1.2]

uniqueElements

返回數(shù)組的所有唯一值。

const uniqueElements = arr => [...new Set(arr)];

uniqueElements([1, 2, 2, 3, 4, 4, 5]); // [1, 2, 3, 4, 5]

without

從數(shù)組中排除給定值。
使用Array.filter()創(chuàng)建一個不包括所有給定值的數(shù)組。

const without = (arr, ...args) => arr.filter(v => !args.includes(v));

without([2, 1, 2, 3], 1, 2); // [3]

xProd

通過從數(shù)組中創(chuàng)建每個可能的對,從提供的兩個數(shù)組中創(chuàng)建一個新數(shù)組。
使用array.prototype.reduce()、array.prototype.map()array.prototype.concat()從兩個數(shù)組的元素中生成每個可能的對,并將它們保存在一個數(shù)組中。

const xProd = (a, b) => a.reduce((acc, x) => acc.concat(b.map(y => [x, y])), []);

xProd([1, 2], ['a', 'b']); // [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]

zip

創(chuàng)建一組元素,根據(jù)原始數(shù)組中的位置進行分組。

const zip = (...arrays) => {
  const maxLength = Math.max(...arrays.map(x => x.length));
  return Array.from({ length: maxLength }).map((_, i) => {
    return Array.from({ length: arrays.length }, (_, k) => arrays[k][i]);
  });
};

zip(['a', 'b'], [1, 2], [true, false]); // [['a', 1, true], ['b', 2, false]]
zip(['a'], [1, 2], [true, false]); // [['a', 1, true], [undefined, 2, false]]

zipObject

給定一個有效屬性標識符數(shù)組和一個值數(shù)組,返回一個將屬性與值關(guān)聯(lián)的對象。

const zipObject = (props, values) =>
  props.reduce((obj, prop, index) => ((obj[prop] = values[index]), obj), {});

zipObject(['a', 'b', 'c'], [1, 2]); // {a: 1, b: 2, c: undefined}
zipObject(['a', 'b'], [1, 2, 3]); // {a: 1, b: 2}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容