30-seconds-of-code JavaScript 数组篇 持续更新

30-seconds-of-code

原文:https://github.com/Chalarangelo/30-seconds-of-code

作者:Chalarangelo

翻译:http://caibaojian.com/30-seconds-of-code.html

译者:蔡宝坚

收集有用的 Javascript 片段, 你可以在30秒或更少的时间里理解。

arrMax:返回数组中得最大值

Math.max()与扩展运算符 (...) 结合使用以获取数组中的最大值。

const arrMax = (arr)=>Math.max(...arr)
arrMin:返回数组中的最小值

Math.min()与扩展运算符 (...) 结合使用以获取数组中的最小值。

const arrMin = arr => Math.min(...arr)
chunkArr:将数组划分为指定大小的较小数组

使用Array.from()创建新的数组, 这符合将生成的区块数。使用Array.slice()将新数组的每个元素映射到size长度的区块。如果原始数组不能均匀拆分, 则最终的块将包含剩余的元素。

const chunkArr = (arr,size) => Array.from({length:Math.ceil( arr.length / size)},(val,index)=>arr.slice(index*size,index*size+size)) //val为 undefined

Array.from(arrayLike[, mapFn[, thisArg]]) 可以通过以下方式来创建数组对象:

  • 伪数组对象(拥有一个 length 属性和若干索引属性的任意对象)
  • 可迭代对象(可以获取对象中的元素,如 Map和 Set 等)

Array.from({length:3},(val,index)=>console.log({val,index})) //[undefined, undefined, undefined]

compact:从数组中移除faley

使用Array.filter()筛选出 falsey 值 (falsenull0""undefinedNaN).

const compact = arr => arr.filter(x=>x!=false)
countOccurrences:计算数组中值出现的次数

使用Array.reduce()在每次遇到数组中的特定值时递增计数器。

const countOccurrences = (arr,value) => arr.reduce((val,curVal)=>curVal===value?val+1:val+0,0)

reducer 函数接收4个参数:

  1. Accumulator (acc) (累计器)

  2. Current Value (cur) (当前值)

  3. Current Index (idx) (当前索引)

  4. Source Array (src) (源数组)

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
pack:选择出想要得元素
function pick(obj, keys) {
    return keys.map(k => k in obj ? {[k]: obj[k]} : {})
               .reduce((res, o) => Object.assign(res, o), {});
}

const row = {
    'accounts.id': 1,
    'client.name': 'John Doe',
    'bank.code': 'MDAKW213'
};

const table = [
    row,
    {'accounts.id': 3, 'client.name': 'Steve Doe', 'bank.code': 'STV12JB'}
];

pick(row, ['client.name']); // 取到了 client name

table.map(row => pick(row, ['client.name'])); // 取到了一系列 client name
pick:从对象中选取对应于给定键得键值对

使用Array.reduce()将筛选/选取的密钥转换回具有相对应的键值对的对象(如果obj中存在该键)

const pick = (obj,arr) => arr.reduce((acc,cur)=>(cur in obj && (acc[cur]=obj[cur]),acc),{})
reject:反筛选给出得元素
function reject(obj, keys) {
    return Object.keys(obj)
        .filter(k => !keys.includes(k))
        .map(k => ({[k]: obj[k]}))
        .reduce((res, o) => Object.assign(res, o), {});
}

// 或者, 利用 pick
function reject(obj, keys) {
    const vkeys = Object.keys(obj)
        .filter(k => !keys.includes(k));
    return pick(obj, vkeys);
}

reject({a: 2, b: 3, c: 4}, ['a', 'b']); // => {c: 4}
countNums:计算每个元素出现的个数
const countNums = arr => arr.reduce((val,curVal)=>{
	if(curVal in val){
		val[curVal]++
	·}else{
		val[curVal]= 1
	·}
	return val
	} 		
,{})

// 更简洁
const countTimes = arr => arr.reduce((prev,next)=>{
	prev[next] = (prev[next] + 1) || 1 
	// 第一次prev[next] + 1 为 undefined  undefined+1==>NaN
	return prev
},{})
countTimes([1,1,2,1,2,3])
deepFlatten:深拼合数组

使用递归。使用Array.concat()与空数组 ([]) 和跨页运算符 (...) 来拼合数组。递归拼合作为数组的每个元素。

const deepFlatten = arr => [].concat(...arr.map(item => Array.isArray(item) ? deepFlatten(item) : item))
intersection:返回两个数组中存在的元素的列表。

b创建Set, 然后使用Array.filter()on a只保留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]
difference:返回俩个数组之间的差异

b创建Set, 然后使用Array.filter() on 只保留a b中不包含的值.

const difference = (leftArr,rightArr) => {const b = new Set(leftArr); return rightArr.filter(x=>!b.has(x))}
difference([1,2,3], [1,2,4])
distinctValuesOfArray:返回数组的所有不同值。

使用 ES6 Set...rest运算符放弃所有重复的值。

const distinctValuesOfArray = arr => [...new Set(arr)]
dropElements

移除数组中的元素, 直到传递的函数返回true。返回数组中的其余元素。 在数组中循环, 使用Array.shift()将数组的第一个元素除去, 直到函数的返回值为true。返回其余元素。

const dropElements = (arr,fn) => {while(arr.length>0 && !fn(arr[0])) arr.shift();return arr}
dropElements([1, 2, 3, 4], n => n >= 3)
everyNth:返回数组中的每个第 n 个元素。

使用Array.filter()创建一个包含给定数组的每个第 n 个元素的新数组。

const everyNth = (arr,n) => arr.filter((val,index)=>index%n===0)
// everyNth([1,2,3,4,5,6], 2) -> [ 1, 3, 5 ]
filterNonUnique:筛选处数组中得非唯一值

对于只包含唯一值得数组,请使用Array.filter()

const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i))
// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5]
flatten:拼合数组

使用Array.reduce()获取数组中得所有元素和concat()以拼合它们

const flatten = arr => arr.reduce((val,curval)=>val.concat(curval),[])
// flatten([1,[2],3,4]) -> [1,2,3,4]
flattenDepath:将数组向上拼合到指定深度

使用递归, 递减depth, 每层深度为1。使用Array.reduce()Array.concat()来合并元素或数组。基本情况下, 对于等于1depth停止递归。省略第二个元素,depth仅拼合到1的深度 (单个拼合)。

const flattenDepth = (arr, depth = 1) =>
depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), [])
: arr.reduce((a, v) => a.concat(v), []);
// flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5]
groupby :根据给定函数对数组元素进行分组。/********************/

使用Array.map()将数组的值映射到函数或属性名。使用Array.reduce()创建一个对象, 其中的键是从映射的结果生成的。

const groupBy = (arr, func) =>
arr.map(typeof func === 'function' ? func : val => val[func])
.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:返回列表得头
const head = arr => arr[0]
initial:返回除最后一个数组之外的所有元素。

使用 “arr.slice(0,-1)” 返回数组的最后一个元素。

const initial = arr => arr.slice(0, -1);
// initial([1,2,3]) -> [1,2] tip:-1 相当于最后一个元素得索引 -2倒数第二个 以此类推
initializeArrayWithRange:初始化包含指定范围内的数字的数组。

使用Array(end-start)创建所需长度的数组Array.map()以填充区域中所需的值。可以省略start以使用默认值0.

const initializeArrayWithRange = (end,strart=0)=>Array.from({length:end-start}).map((v,index)=>index + start)
// initializeArrayWithRange(5) -> [0,1,2,3,4]
initializeArrayWithValues: 初始化并填充具有指定值的数组。

使用Array(n)创建所需长度的数组,fill(v)以填充所需的值。可以省略value以使用默认值0.

const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value);
const initializeArrayWithValues = (n, value = 0) => Array.from({length:n}).fill(value);
// initializeArrayWithValues(5, 2) -> [2,2,2,2,2]
last:返回数组中最后一个元素
const last = arr => arr[arr.length - 1];
const last = arr => arr.slice(-1);
// last([1,2,3]) -> 3
mapObject:使用函数将数组的值映射到对象, 其中键值对由原始值作为键和映射值组成。/*********/

使用匿名内部函数范围来声明未定义的内存空间, 使用闭包来存储返回值。使用新的Array可将该数组与函数的映射放在其数据集上, 而逗号运算符返回第二个步骤, 而不需要从一个上下文移动到另一个环境 (由于关闭和操作顺序)。

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 }
*/
nthElement:返回数组的第 n 个元素。

使用Array.slice()可获取包含第 n 个元素的数组。如果索引超出界限, 则返回[]。省略第二个参数n, 以获取数组的第一个元素。

const nthElement = (arr, n=0) => (n>0? arr.slice(n,n+1) : arr.slice(n))[0];
// nthElement(['a','b','c'],1) -> 'b'
// nthElement(['a','b','b'],-3) -> 'a'
pull:对原数组进行变异,以筛选出指定的值

使用Array.filter()Array.includes()来拉取出不需要的值,使用Array.length=0可将传入的数组的长度重置为零,并将其设置为Array.push()。以便仅使用所提取的值填充它

const pull = (arr,...args) => {
    const pulled = arr.filter((val,index)=>!args.include(val));
    arr.length=0;
    pulled.forEach(v=>arr.push(v))
}
// let myArray = ['a', 'b', 'c', 'a', 'b', 'c'];
// pull(myArray, 'a', 'c');
// console.log(myArray) -> [ 'b', 'b' ]
remove:从数组中移除给定函数返回false的元素. 使用Array.filter()查找返回 truthy 值的数组元素和Array.reduce()以使用Array.splice()删除元素。使用三参数 (func 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:返回数组中的随机元素

使用Math.random()生成一个随机数, 将它与length相乘, 并使用数学将其舍入到最接近的整数Math.floor()。此方法也适用于字符串。

const sample = arr => arr[Math.floor(Math.random() * arr.length)];
// sample([3, 7, 9, 11]) -> 9
symmetricDifference:返回两个数组之间的对称差

从每个数组创建一个Set, 然后对它们中的每一个都使用Array.filter(), 以便只保留其他值中不包含的数值。

const symmetricDifference = (a,b)=>{
	const aArr = new Set(a), bArr= new Set(b);
	return [...aArr.filter(x=>!bArr.has(x)),...bArr.filter(x=>!aArr.has(x))]
}
// symmetricDifference([1,2,3], [1,2,4]) -> [3,4]
tail:返回数组中的所有元素,除第一个

如果数组的length大于1,则返回arr.slice(1),否则返回整个数组

const tail = arr => arr.length > 1 ? arr.slice(1) : arr;
// tail([1,2,3]) -> [2,3]
// tail([1]) -> [1]
take:返回一个数组, 其中 n 个元素从开始处移除。

使用Array.slice()创建数组的切片, 其中包含从开始处取出的n元素。

const take = (arr, n = 1) => arr.slice(0, n);
// take([1, 2, 3], 5) -> [1, 2, 3]
// take([1, 2, 3], 0) -> []
takeRight:返回一个数组, 其中 n 个元素从末尾移除。

使用Array.slice()创建数组的切片, 其中包含从末尾取出的n元素。

const takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length);
// takeRight([1, 2, 3], 2) -> [ 2, 3 ]
// takeRight([1, 2, 3]) -> [3]
union:返回在两个数组中的任意一个中存在的每个元素。

创建一个Set, 其中包含ab的所有值, 并将其转换为数组。

const union = (a,b) => Array.from(new Set([...a,...b]))
// union([1,2,3], [4,3,2]) -> [1,2,3,4]
without:筛选出数组中具有指定值之一的元素。

使用Array.filter()创建不包括的数组 (使用!Array.includes()) 所有给定值。

const without = (arr, ...args) => arr.filter(v => !args.includes(v));
// without([2, 1, 2, 3], 1, 2) -> [3]

zip/******/

创建基于原始数组中的位置分组的元素数组。

使用Math.max.apply()获取参数中最长的数组。创建一个以该长度为返回值的数组, 并使用 map 函数创建一个分组元素的数组Array.from()如果参数数组的长度不同, 则在未找到任何值的情况下使用undefined

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]]

你可能感兴趣的:(JS)