本系列翻译自开源项目 30-seconds-of-code 这是一个非常优秀的系列,不是说真的三十秒就能理解,也需要你认真的思考,其中有一些点非常精妙,很值得一读。 本文在我的github同步更新,点击文章末尾阅读全文你可以看到当前翻译的全部系列。 如果您对本期有不同或者更好的见解,请后台留言,喜欢请点个好看,谢谢阅读。
将数组分成指定大小的较小数组。
使用 Array.from()
创建一个新的数组,该数组与将要生成的块的数量相匹配。 使用 Array.prototype.slice()
将新数组的每个元素映射到长度为 size
的块。 如果原始的数组不能被均匀的分割,最后的一块将包含剩余的元素。
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]]
删除数组中错误的元素
使用 Array.prototype.filter()
过滤掉错误的元素 ( false
, null
, 0
, ""
, undefined
, 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 ]
基于给定的函数将数组中的元素进行分组,并返回每个组中的元素数。
使用 Array.prototype.map()
来将数组中的每个元素映射到函数或属性名。 使用 Array.prototype.reduce()
创建一个对象,其中的键是从映射结果生成的。
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}
计算数组中某个元素出现的次数。
Use Array.prototype.reduce()
在每次遇到数组中的特定值时递增计数器。
const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);
示例
countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3
将一个多层嵌套的数组转转换成一个一元数组。
使用递归. 使用 Array.prototype.concat()
和一个空数组( []
)以及展开运算符( ...
)来平铺一个数组。 当每个元素还是一个数字时,递归铺平他。
const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));
示例
deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]
返回两个数组间的差异值。
从数组 b
中创建一个 Set
,然后用使用另一个数组 a
的 Array.prototype.filter()
方法过滤掉 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]
将提供的函数应用于两个数组的每个数组元素后,返回两个数组中不同的元素。
通过 b
中的每个元素调用 fn
后创建一个 Set
,然后将 Array.prototype.filter()
与 fn
调用后的 a
结合使用,只保留先前创建的集合中不包含的值。
const differenceBy = (a, b, fn) => { const s = new Set(b.map(fn)); return a.filter(x => !s.has(fn(x)));};
示例
differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [1.2]differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], v => v.x); // [ { x: 2 } ]
筛选出比较器函数不返回 true
的数组中的所有值。
使用 Array.prototype.filter()
和 Array.prototype.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]
返回一个新数组,从原数组左边删除 n
个元素。
使用 Array.prototype.slice()
从左侧删除指定数量的元素。
const drop = (arr, n = 1) => arr.slice(n);
slice(n) 表示取数组下标n以后的元素(含n)
示例
drop([1, 2, 3]); // [2,3]drop([1, 2, 3], 2); // [3]drop([1, 2, 3], 42); // []
返回一个新数组,从原数组右边删除 n
个元素。
使用 Array.prototype.slice()
从右边删除指定数目的元素。
const dropRight = (arr, n = 1) => arr.slice(0, -n);
slice(0, -n) 表示取数组第一个到倒数第n个元素(不含-n)
示例
dropRight([1, 2, 3]); // [1,2]dropRight([1, 2, 3], 2); // [1]dropRight([1, 2, 3], 42); // []
从数组尾部移除数组中的元素,直到传递的函数返回 true
。返回数组中剩余的元素。
遍历数组,使用 Array.prototype.slice()
删除数组的最后一个元素,直到函数的返回值为 true
。返回剩余的元素。
const dropRightWhile = (arr, func) => { while (arr.length > 0 && !func(arr[arr.length - 1])) arr = arr.slice(0, -1); return arr;};
示例
dropRightWhile([1, 2, 3, 4], n => n < 3); // [1, 2]
移除数组中的元素,直到传递的函数返回 true
。返回数组中剩余的元素。
遍历数组,使用 Array.prototype.slice()
删除数组的第一个元素,直到函数的返回值为 true
。返回剩余的元素。
const dropWhile = (arr, func) => { while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1); return arr;};
示例
dropWhile([1, 2, 3, 4], n => n >= 3); // [3,4]