使用 Ctrl + F or command + F来搜索代码片段
目录
- 🔌 Adapter
- 📚 Array
- chunk(数组分块)
- compact(过滤掉数组中所有假值元素)
- countBy(根据条件对数组分组)
- countOccurrences(计数数组中某个值的出现次数)
- deepFlatten(深度平铺数组)
- difference(数组比较)
- differenceBy(给定条件进行数组比较)
- differenceWith(通过比较函数比较两个数组的差异)
- drop(数组删除)
- dropRight(从右边删除数组)
- dropRightWhile(根据函数从右删除元素)
- dropWhile(根据函数删除元素)
- everyNth( 获得数组中的每个第 n 个元素)
- filterNonUnique(数组去重)
- findLast(获取符合条件的最后一个元素)
- findLastIndex(获取符合条件的最后一个元素索引)
- flatten(平铺数组)
- forEachRight( 从数组的最后一个元素开始遍历数组)
- groupBy(数组分组)
- head(获取数组的第一个元素)
- indexOfAll(返回指定元素的所有索引)
- initial(排除数组中最后一个元素)
- initialize2DArray(初始化一个二维数组)
- initializeArrayWithRange(初始化特定范围的数字数组)
- initializeArrayWithRangeRight
- initializeArrayWithValues(初始化特定范围和值的数组)
- intersection(数组交集)
- intersectionBy(根据应用给定函数后求交集)
- intersectionWith(根据条件求交集)
- isSorted(是否为排序数组)
- join(将数组的所有元素拼接成一个字符串)
- last(获取数组的最后一个元素)
- longestItem(获取最长元素)
- mapObject(将数组的值映射到对象)
- maxN(返回数组中N个最大元素)
- minN(返回数组中N个最小元素)
- nthElement(获取数组的第N个元素)
- partition(数组元素分组)
- pull(删除数组中指定的值)
- pullAtIndex(删除数组中指定索引的值)
- pullAtValue(删除数组中指定的值,返回删除的元素)
- pullBy
🔌 Adapter
ary(指定函数参数个数)
创建一个函数且接受最多 n 个参数,忽略多余参数。
调用传入的函数 fn 并传入给定的 n 个参数。
参数通过 Array.slice(0,n) 截取,并使用(…)解构。
const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
// 示例
const firstTwoMax = ary(Math.max, 2);
[[2, 6, 'a'], [8, 4, 6], [10]].map(x => firstTwoMax(...x)); // [6, 8, 10]
call(函数组合)
给定一个 key 和一个 set 作为参数,给定上下文时调用它们。主要用于函数组合。
使用闭包以存储的参数调用存储的 key 。
const call = (key, ...args) => context => context[key](...args);
// 示例
Promise.resolve([1, 2, 3])
.then(call('map', x => 2 * x))
.then(console.log); //[ 2, 4, 6 ]
const map = call.bind(null, 'map');
Promise.resolve([1, 2, 3])
.then(map(x => 2 * x))
.then(console.log); //[ 2, 4, 6 ]
collectInto(将接受数组的函数更改为可变参数函数。)
将接受数组的函数更改为可变参数函数。
给定一个函数,返回一个闭包,将所有输入收集到一个接受函数的数组中。
const collectInto = fn => (...args) => fn(args);
// 示例
const Pall = collectInto(Promise.all.bind(Promise));
let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2);
let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3));
Pall(p1, p2, p3).then(console.log); // [1, 2, 3] (after about 2 seconds)
flip(翻转函数参数)
Flip接受函数作为参数,然后将函数第一个参数作为最后一个参数。
返回一个包含可变参数输入的闭包,并且在应用其余参数之前将最后一个参数拼接成第一个参数。
const flip = fn => (first, ...rest) => fn(...rest, first);
// 示例
let a = { name: 'John Smith' };
let b = {};
const mergeFrom = flip(Object.assign);
let mergePerson = mergeFrom.bind(null, a);
mergePerson(b); // == b
b = {};
Object.assign(b, a); // == b
over(同一参数调用多个函数)
创建一个函数,用它接收到的参数调用每个提供的函数,并返回结果。
使用 Array.map()和 Function.apply() 将给定的参数应用到每个函数。
const over = (...fns) => (...args) => fns.map(fn => fn.apply(null, args));
// 示例
const minMax = over(Math.min, Math.max);
minMax(1, 2, 3, 4, 5); // [1,5]
overArgs(参数转换器)
给定一个函数,通过指定函数转变其参数后再调用。
使用Array.map()与展开操作符(…),通过transforms来转换参数并传递给 fn 。
const overArgs = (fn, transforms) => (...args) => fn(...args.map((val, i) => transforms[i](val)));
// 示例
let square = a => a * a;
let doubled = b => 2 * b;
var func = overArgs(
function(x, y) {
return [x, y];
},
[square, doubled]
);
func(9, 3); // [81, 6]
pipeAsyncFunctions(顺序执行异步函数)
从左到右的执行异步函数组合。
使用Array.reduce()与展开操作符(…),从左到右使用Promise.then()执行函数组合。
这些函数可以返回:简单值,Promise的组合或者定义为通过await返回的异步。
所有函数必须是一元函数。
const pipeAsyncFunctions = (...fns) => arg => fns.reduce((p, f) => p.then(f), Promise.resolve(arg));
// 示例
const sum = pipeAsyncFunctions(
x => x + 1,
x => new Promise(resolve => setTimeout(() => resolve(x + 2), 1000)),
x => x + 3,
async x => (await x) + 4
);
(async () => {
console.log(await sum(5)); // 15 (after one second)
})();
pipeFunctions(从左到右的执行函数组合)
执行从左到右的函数组合。
使用 Array.reduce() 与展开操作符 (…) 来执行从左到右的函数组合。第一个(最左边的)函数可以接受一个或多个参数;其余的函数必须是一元函数。
const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
// 示例
const add5 = x => x + 5;
const multiply = (x, y) => x * y;
const multiplyAndAdd5 = pipeFunctions(multiply, add5);
multiplyAndAdd5(5, 2); // 15
promisify(柯里化一个 Promise 函数)
转换一个异步函数,以返回一个 promise 。
使用柯里化返回一个函数,这个函数返回一个调用原始函数的 Promise 。 使用 …rest 运算符传入所有参数。
在 Node 8+ 中,你可以使用 util.promisify
const promisify = func => (...args) =>
new Promise((resolve, reject) =>
func(...args, (err, result) => (err ? reject(err) : resolve(result)))
);
// 示例
const delay = promisify((d, cb) => setTimeout(cb, d));
delay(2000).then(() => console.log('Hi!')); // Promise resolves after 2s
rearg(参数重新排列)
创建一个函数调用给定的函数,给定的函数参数按照指定的索引排列。
基于 indexes 使用 Array.reduce() 和 Array.indexOf() 重排参数,使用展开操作符 (…) 向给定函数传参。
const rearg = (fn, indexes) => (...args) =>
fn(
...args.reduce(
(acc, val, i) => ((acc[indexes.indexOf(i)] = val), acc),
Array.from({ length: indexes.length })
)
);
// 示例
var rearged = rearg(
function(a, b, c) {
return [a, b, c];
},
[2, 0, 1]
);
rearged('b', 'c', 'a'); // ['a', 'b', 'c']
spreadOver(将参数数组映射到该函数的输入)
接受一个可变参数函数并返回一个闭包,该闭包接受一个参数数组映射到该函数的输入。
使用闭包和展开运算符 (…) 将参数数组映射到函数的输入。
const spreadOver = fn => argsArr => fn(...argsArr);
// 示例
const arrayMax = spreadOver(Math.max);
arrayMax([1, 2, 3]); // 3
unary(只接受一个参数的函数)
创建一个最多接受一个参数的函数,忽略任何附加参数。
调用给定函数,只传入第一个参数。
const unary = fn => val => fn(val);
// 示例
['6', '8', '10'].map(unary(parseInt)); // [6, 8, 10]
📚 Array
chunk(数组分块)
把一个数组分块成指定大小的小数组。
使用 Array.from() 创建一个新的数组,它的长度就是生成 chunk(块) 的数量。 使用 Array.slice() 将新数组的每个元素映射到长度为 size 的 chunk 中。 如果原始数组不能均匀分割,最后的 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(过滤掉数组中所有假值元素)
从数组中移除 falsey 值元素。
使用 Array.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 ]
countBy(根据条件对数组分组)
根据给定的函数对数组的元素进行分组,并返回每个组中元素的数量。
使用 Array.map() 将数组的值映射到函数或属性名称。 使用Array.reduce() 创建一个对象,其中的键是从映射的结果中产生的。
const countBy = (arr, fn) =>
arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val, i) => {
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(计数数组中某个值的出现次数)
计算数组中值的出现次数。
每次遇到数组中的某个特定值时,使用 Array.reduce() 来递增计数器。
const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a + 0), 0);
// 示例
countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3
deepFlatten(深度平铺数组)
深度平铺一个数组。
使用递归。 通过空数组([]) 使用 Array.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]
difference(数组比较)
返回两个数组之间的差异。
根据数组 b 创建一个 Set 对象,然后在数组 a 上使用 Array.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]
differenceBy(给定条件进行数组比较)
将给定函数应用于两个数组元素之后,返回两个数组之间的差异。
通过对 b 中的每个元素应用 fn 后创建一个 Set 对象,然后在数组 a 上使用 Array.filter() 和 fn ,只保留之前创建的集合中不包含的值。
const differenceBy = (a, b, fn) => {
const s = new Set(b.map(v => fn(v)));
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 } ]
differenceWith(通过比较函数比较两个数组的差异)
过滤掉比较函数不返回true的数组中的所有值。
使用 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(数组删除)
从左边删除n个元素,并返回新数组。
使用 Array.slice()从左侧删除指定数量的元素。
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个元素,并返回新数组。
使用 Array.slice()从右侧删除指定数量的元素。
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); // []
dropRightWhile(根据函数从右删除元素)
从数组末尾移除元素,直到传递的函数返回true。 返回数组中的其余元素。
循环访问数组,使用Array.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]
dropWhile(根据函数删除元素)
删除数组中的元素,直到传递的函数返回true。 返回数组中的其余元素。
循环访问数组,使用Array.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]
everyNth( 获得数组中的每个第 n 个元素)
返回数组中的每个第 n 个元素。
使用 Array.filter() 创建一个包含给定数组的每个第 n 个元素的新数组。
const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1);
// 示例
everyNth([1, 2, 3, 4, 5, 6], 2); // [ 2, 4, 6 ]
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]
findLast(获取符合条件的最后一个元素)
返回给定函数返回 true 的最后一个元素。
使用 Array.filter()移除 fn 返回 false的元素,Array.slice(-1)获取最后一个元素。
const findLast = (arr, fn) => arr.filter(fn).slice(-1)[0];
// 示例
findLast([1, 2, 3, 4], n => n % 2 === 1); // 3
findLastIndex(获取符合条件的最后一个元素索引)
返回给定函数返回 true 的最后一个元素的索引。
使用 Array.map() 将每个元素映射到具有索引和值的数组。 使用Array.filter() 移除fn返回 false 的元素,Array.slice(-1) 获取最后一个元素。
const findLastIndex = (arr, fn) =>
arr
.map((val, i) => [i, val])
.filter(val => fn(val[1], val[0], arr))
.slice(-1)[0][0];
// 示例
findLastIndex([1, 2, 3, 4], n => n % 2 === 1); // 2 (index of the value 3)
flatten(平铺数组)
使用递归,为每个深度级别 depth 递减 1 。 使用 Array.reduce() 和 Array.concat() 来合并元素或数组。 基本情况下,depth 等于 1 停止递归。 省略第二个参数,depth 只能平铺到 1 (单层平铺) 的深度。
const flatten = (arr, depth = 1) =>
depth != 1
? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v, depth - 1) : v), [])
: arr.reduce((a, v) => a.concat(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]
forEachRight( 从数组的最后一个元素开始遍历数组)
从数组的最后一个元素开始,为每个数组元素执行一次提供的函数。
使用 Array.slice(0) 克隆给定的数组,Array.reverse() 反转数组,Array.forEach() 遍历这个反向数组。
const forEachRight = (arr, callback) =>
arr
.slice(0)
.reverse()
.forEach(callback);
// 示例
forEachRight([1, 2, 3, 4], val => console.log(val)); // '4', '3', '2', '1'
groupBy(数组分组)
根据给定的函数对数组元素进行分组。
使用 Array.map() 将数组的值映射到函数或属性名称。使用 Array.reduce() 来创建一个对象,其中的 key 是从映射结果中产生。
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(获取数组的第一个元素)
返回数组的第一个元素。
使用 arr[0] 返回传递数组的第一个元素。
const head = arr => arr[0];
// 示例
head([1, 2, 3]); // 1
indexOfAll(返回指定元素的所有索引)
返回数组中所有 val 的索引。 如果 val 从不出现,则返回 [] 。
使用 Array.forEach() 循环元素和 Array.push() 来存储匹配元素的索引。 返回索引数组。
const indexOfAll = (arr, val) => {
const indices = [];
arr.forEach((el, i) => el === val && indices.push(i));
return indices;
};
// 示例
indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []
initial(排除数组中最后一个元素)
返回一个数组中除了最后一个元素以外的所有元素。
使用 arr.slice(0,-1) 返回排除了最后一个元素的数组。
const initial = arr => arr.slice(0, -1);
// 示例
initial([1, 2, 3]); // [1,2]
initialize2DArray(初始化一个二维数组)
初始化一个给定行数和列数,及值的二维数组。
使用 Array.map() 生成 h 行,其中每个行都是一个长度为 w 的新数组。 如果未提供值 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(初始化特定范围的数字数组)
初始化一个数组,该数组包含指定范围内的数字,包括 start 和 end ,数字间隔为 step 。
使用 Array.from(Math.ceil((end+1-start)/step)) 创建一个所需长度的数组(元素的数量等于 (end-start)/step 或者 (end+1-start)/step 包括 end ), 用 Array.map() 填充在这个范围内要求的值。 你可以省略 start 来使用默认值 0。 您可以省略 step 使用默认值 1 。
const initializeArrayWithRange = (end, start = 0, step = 1) =>
Array.from({ length: Math.ceil((end + 1 - start) / step) }).map((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]
initializeArrayWithRangeRight
初始化一个数组,该数组包含指定范围内的数字(反向),包括 start 和 end ,数字间隔为 step 。
使用 Array.from(Math.ceil((end+1-start)/step)) 创建一个所需长度的数组(元素的数量等于 (end-start)/step 或者 (end+1-start)/step 包括 end ), 用 Array.map() 填充在这个范围内要求的值。 你可以省略 start 来使用默认值 0。 您可以省略 step 使用默认值 1 。
const initializeArrayWithRangeRight = (end, start = 0, step = 1) =>
Array.from({ length: Math.ceil((end + 1 - start) / step) }).map(
(v, i, arr) => (arr.length - i - 1) * step + start
);
// 示例
initializeArrayWithRangeRight(5); // [5,4,3,2,1,0]
initializeArrayWithRangeRight(7, 3); // [7,6,5,4,3]
initializeArrayWithRangeRight(9, 0, 2); // [8,6,4,2,0]
initializeArrayWithValues(初始化特定范围和值的数组)
使用指定的值初始化和填充数组。
使用 Array(n) 创建所需长度的数组,使用 fill(v) 以填充所需的值。 你可以忽略 val ,使用默认值 0。
const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);
// 示例
const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);
intersection(数组交集)
返回两个数组中都存在的元素列表。
根据数组 b 创建一个 Set 对象,然后在数组 a 上使用 Array.filter() 方法,只保留数组 b 中也包含的值。
const intersection = (a, b) => {
const s = new Set(b);
return a.filter(x => s.has(x));
};
// 示例
const intersection = (a, b) => {
const s = new Set(b);
return a.filter(x => s.has(x));
};
intersectionBy(根据应用给定函数后求交集)
将给定函数应用于两个数组元素之后,返回两个数组中存在的元素列表。
通过将fn应用于b中的所有元素来创建一个Set,然后在a上使用Array.filter()来保留应用 fn 后包含在b中的值的元素。
const intersectionBy = (a, b, fn) => {
const s = new Set(b.map(x => fn(x)));
return a.filter(x => s.has(fn(x)));
};
// 示例
intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [2.1]
intersectionWith(根据条件求交集)
根据给定函数,求两个数组交集。
使用Array.filter()和 Array.findIndex()与给定的比较器结合确定相交值。
const intersectionWith = (a, b, comp) => a.filter(x => b.findIndex(y => comp(x, y)) !== -1);
// 示例
intersectionWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0, 3.9], (a, b) => Math.round(a) === Math.round(b)); // [1.5, 3, 0]
isSorted(是否为排序数组)
如果数组按升序排序,则返回 1 ;如果按降序排列则返回-1 ;如果未排序则返回0。
计算前两个元素的排序方向 direction 。 使用 Object.entries() 来循环使用数组对象并对它们进行比较。 如果 direction 改变,则返回 0 ,如果直到最后一个元素, direction 没有改变,则返回 direction 。
const isSorted = arr => {
const direction = arr[0] > arr[1] ? -1 : 1;
for (let [i, val] of arr.entries())
if (i === arr.length - 1) return direction;
else if ((val - arr[i + 1]) * direction > 0) return 0;
};
//示例
isSorted([0, 1, 2, 2]); // 1
isSorted([4, 3, 2]); // -1
isSorted([4, 3, 5]); // 0
join(将数组的所有元素拼接成一个字符串)
将数组的所有元素拼接成一个字符串并返回此字符串。 使用分隔符和结束分隔符。
使用 Array.reduce() 将元素拼接成一个字符串。 省略第二个参数 separator ,则默认使用分隔符’,’。 省略第三个参数 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(获取数组的最后一个元素)
返回数组中的最后一个元素。
使用 arr.length - 1 来计算给定数组的最后一个元素的索引并返回。
const last = arr => arr[arr.length - 1];
//示例
last([1, 2, 3]); // 3
longestItem(获取最长元素)
获取任何数量的可迭代对象或具有 length 属性的对象,并返回最长的一个。
使用 Array.sort() 按 length 对所有参数进行排序,返回第一个(最长)元素。
const longestItem = (...vals) => [...vals].sort((a, b) => b.length - a.length)[0];
//示例
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(将数组的值映射到对象)
使用一个函数将数组的值映射到对象,其键值对中,原始值作为键,映射值作为值。
使用一个匿名的内部函数作用域来声明一个 undefined 的内存空间,使用闭包来存储返回值。 使用一个新的 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 }
maxN(返回数组中N个最大元素)
从提供的数组中返回 n 个最大元素。如果 n 大于或等于提供的数组长度,则返回原数组(按降序排列)。
结合使用Array.sort() 与展开操作符(…) ,创建一个数组的浅克隆,并按降序排列。 使用 Array.slice() 以获得指定的元素个数。 忽略第二个参数 n ,默认获取单个元素(以数组的形式)。
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(返回数组中N个最小元素)
从提供的数组中返回 n 个最小元素。如果 n 大于或等于提供的数组长度,则返回原数组(按降序排列)。
结合使用Array.sort() 与展开操作符(…) ,创建一个数组的浅克隆,并按降序排列。 使用 Array.slice() 以获得指定的元素个数。 忽略第二个参数 n ,默认获取单个元素(以数组的形式)。
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(获取数组的第N个元素)
返回数组的第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'
partition(数组元素分组)
根据所提供的函数对每个元素进行迭代,将这些元素分成两个数组。
使用 Array.reduce() 创建两个数组的数组。 使用 Array.push() 将 fn 返回为 true 的元素添加到第一个数组,而 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(删除数组中指定的值)
改变原始数组,过滤掉指定的值。
使用 Array.filter() 和 Array.includes() 来剔除指定的值。使用 Array.length = 0 将数组中的长度重置为零,并且通过 Array.push() 只使用 pulled 值重新填充数组。
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(删除数组中指定索引的值)
改变原始数组,过滤掉指定索引的值。
使用 Array.filter() 和 Array.includes() 来剔除指定的值。使用 Array.length = 0 将数组中的长度重置为零, 并且通过 Array.push() 只使用 pulled 值重新填充数组。使用 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(删除数组中指定的值,返回删除的元素)
改变原始数组,过滤出指定的值。 返回删除的元素。
使用 Array.filter() 和 Array.includes() 来剔除指定的值。使用 Array.length = 0 将数组中的长度重置为零, 并且通过 Array.push() 只使用 pulled 值重新填充数组。使用 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' ]
pullBy
根据给定的迭代器函数,将原始数组改变为过滤出指定的值。
检查函数中提供的最后一个参数。 使用Array.map()将迭代器函数fn应用于所有数组元素。 使用Array.filter()和Array.includes()来提取不需要的值。 使用Array.length = 0可以通过将数组的长度重置为零来改变传入的数组,Array.push()只用拉取的值重新填充数组。
const pullBy = (arr, ...args) => {
const length = args.length;
let fn = length > 1 ? args[length - 1] : undefined;
fn = typeof fn == 'function' ? (args.pop(), fn) : undefined;
let argState = (Array.isArray(args[0]) ? args[0] : args).map(val => fn(val));
let pulled = arr.filter((v, i) => !argState.includes(fn(v)));
arr.length = 0;
pulled.forEach(v => arr.push(v));
};
//示例
var myArray = [{ x: 1 }, { x: 2 }, { x: 3 }, { x: 1 }];
pullBy(myArray, [{ x: 1 }, { x: 3 }], o => o.x); // myArray = [{ x: 2 }]
未完待续…
写于 2018年01月31日Web 5327
如非特别注明,文章皆为原创。
转载请注明出处: https://www.liayal.com/article/5a7177acfb1bf64cecfdee9e
记小栈小程序上线啦~搜索【记小栈】或【点击扫码】体验
~ 评论还没有,沙发可以有 O(∩_∩)O~