值得收藏的JavaScript 代码片段(不断更新)

2018年1月31日Web 922

使用 Ctrl + F or command + F来搜索代码片段

目录

🔌 Adapter

ary(指定函数参数个数)

创建一个函数且接受最多 n 个参数,忽略多余参数。

调用传入的函数 fn 并传入给定的 n 个参数。

参数通过 Array.slice(0,n) 截取,并使用(…)解构。

  1. const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
  1. // 示例
  2. const firstTwoMax = ary(Math.max, 2);
  3. [[2, 6, 'a'], [8, 4, 6], [10]].map(x => firstTwoMax(...x)); // [6, 8, 10]

call(函数组合)

给定一个 key 和一个 set 作为参数,给定上下文时调用它们。主要用于函数组合。

使用闭包以存储的参数调用存储的 key 。

  1. const call = (key, ...args) => context => context[key](...args);
  1. // 示例
  2. Promise.resolve([1, 2, 3])
  3. .then(call('map', x => 2 * x))
  4. .then(console.log); //[ 2, 4, 6 ]
  5. const map = call.bind(null, 'map');
  6. Promise.resolve([1, 2, 3])
  7. .then(map(x => 2 * x))
  8. .then(console.log); //[ 2, 4, 6 ]

collectInto(将接受数组的函数更改为可变参数函数。)

将接受数组的函数更改为可变参数函数。

给定一个函数,返回一个闭包,将所有输入收集到一个接受函数的数组中。

  1. const collectInto = fn => (...args) => fn(args);
  1. // 示例
  2. const Pall = collectInto(Promise.all.bind(Promise));
  3. let p1 = Promise.resolve(1);
  4. let p2 = Promise.resolve(2);
  5. let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3));
  6. Pall(p1, p2, p3).then(console.log); // [1, 2, 3] (after about 2 seconds)

flip(翻转函数参数)

Flip接受函数作为参数,然后将函数第一个参数作为最后一个参数。

返回一个包含可变参数输入的闭包,并且在应用其余参数之前将最后一个参数拼接成第一个参数。

  1. const flip = fn => (first, ...rest) => fn(...rest, first);
  1. // 示例
  2. let a = { name: 'John Smith' };
  3. let b = {};
  4. const mergeFrom = flip(Object.assign);
  5. let mergePerson = mergeFrom.bind(null, a);
  6. mergePerson(b); // == b
  7. b = {};
  8. Object.assign(b, a); // == b

over(同一参数调用多个函数)

创建一个函数,用它接收到的参数调用每个提供的函数,并返回结果。

使用 Array.map()和 Function.apply() 将给定的参数应用到每个函数。

  1. const over = (...fns) => (...args) => fns.map(fn => fn.apply(null, args));
  1. // 示例
  2. const minMax = over(Math.min, Math.max);
  3. minMax(1, 2, 3, 4, 5); // [1,5]

overArgs(参数转换器)

给定一个函数,通过指定函数转变其参数后再调用。

使用Array.map()与展开操作符(…),通过transforms来转换参数并传递给 fn 。

  1. const overArgs = (fn, transforms) => (...args) => fn(...args.map((val, i) => transforms[i](val)));
  1. // 示例
  2. let square = a => a * a;
  3. let doubled = b => 2 * b;
  4. var func = overArgs(
  5. function(x, y) {
  6. return [x, y];
  7. },
  8. [square, doubled]
  9. );
  10. func(9, 3); // [81, 6]

pipeAsyncFunctions(顺序执行异步函数)

从左到右的执行异步函数组合。
使用Array.reduce()与展开操作符(…),从左到右使用Promise.then()执行函数组合。

这些函数可以返回:简单值,Promise的组合或者定义为通过await返回的异步。

所有函数必须是一元函数。

  1. const pipeAsyncFunctions = (...fns) => arg => fns.reduce((p, f) => p.then(f), Promise.resolve(arg));
  1. // 示例
  2. const sum = pipeAsyncFunctions(
  3. x => x + 1,
  4. x => new Promise(resolve => setTimeout(() => resolve(x + 2), 1000)),
  5. x => x + 3,
  6. async x => (await x) + 4
  7. );
  8. (async () => {
  9. console.log(await sum(5)); // 15 (after one second)
  10. })();

pipeFunctions(从左到右的执行函数组合)

执行从左到右的函数组合。

使用 Array.reduce() 与展开操作符 (…) 来执行从左到右的函数组合。第一个(最左边的)函数可以接受一个或多个参数;其余的函数必须是一元函数。

  1. const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
  1. // 示例
  2. const add5 = x => x + 5;
  3. const multiply = (x, y) => x * y;
  4. const multiplyAndAdd5 = pipeFunctions(multiply, add5);
  5. multiplyAndAdd5(5, 2); // 15

promisify(柯里化一个 Promise 函数)

转换一个异步函数,以返回一个 promise 。

使用柯里化返回一个函数,这个函数返回一个调用原始函数的 Promise 。 使用 …rest 运算符传入所有参数。

在 Node 8+ 中,你可以使用 util.promisify

  1. const promisify = func => (...args) =>
  2. new Promise((resolve, reject) =>
  3. func(...args, (err, result) => (err ? reject(err) : resolve(result)))
  4. );
  1. // 示例
  2. const delay = promisify((d, cb) => setTimeout(cb, d));
  3. delay(2000).then(() => console.log('Hi!')); // Promise resolves after 2s

rearg(参数重新排列)

创建一个函数调用给定的函数,给定的函数参数按照指定的索引排列。

基于 indexes 使用 Array.reduce() 和 Array.indexOf() 重排参数,使用展开操作符 (…) 向给定函数传参。

  1. const rearg = (fn, indexes) => (...args) =>
  2. fn(
  3. ...args.reduce(
  4. (acc, val, i) => ((acc[indexes.indexOf(i)] = val), acc),
  5. Array.from({ length: indexes.length })
  6. )
  7. );
  1. // 示例
  2. var rearged = rearg(
  3. function(a, b, c) {
  4. return [a, b, c];
  5. },
  6. [2, 0, 1]
  7. );
  8. rearged('b', 'c', 'a'); // ['a', 'b', 'c']

spreadOver(将参数数组映射到该函数的输入)

接受一个可变参数函数并返回一个闭包,该闭包接受一个参数数组映射到该函数的输入。

使用闭包和展开运算符 (…) 将参数数组映射到函数的输入。

  1. const spreadOver = fn => argsArr => fn(...argsArr);
  1. // 示例
  2. const arrayMax = spreadOver(Math.max);
  3. arrayMax([1, 2, 3]); // 3

unary(只接受一个参数的函数)

创建一个最多接受一个参数的函数,忽略任何附加参数。

调用给定函数,只传入第一个参数。

  1. const unary = fn => val => fn(val);
  1. // 示例
  2. ['6', '8', '10'].map(unary(parseInt)); // [6, 8, 10]

📚 Array

chunk(数组分块)

把一个数组分块成指定大小的小数组。

使用 Array.from() 创建一个新的数组,它的长度就是生成 chunk(块) 的数量。 使用 Array.slice() 将新数组的每个元素映射到长度为 size 的 chunk 中。 如果原始数组不能均匀分割,最后的 chunk 将包含剩余的元素。

  1. const chunk = (arr, size) =>
  2. Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
  3. arr.slice(i * size, i * size + size)
  4. );
  1. // 示例
  2. chunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]

compact(过滤掉数组中所有假值元素)

从数组中移除 falsey 值元素。

使用 Array.filter() 过滤掉数组中所有 假值元素(false, null, 0, “”, undefined, 和 NaN)。

  1. const compact = arr => arr.filter(Boolean);
  1. // 示例
  2. compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]); // [ 1, 2, 3, 'a', 's', 34 ]

countBy(根据条件对数组分组)

根据给定的函数对数组的元素进行分组,并返回每个组中元素的数量。

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

  1. const countBy = (arr, fn) =>
  2. arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val, i) => {
  3. acc[val] = (acc[val] || 0) + 1;
  4. return acc;
  5. }, {});
  1. // 示例
  2. countBy([6.1, 4.2, 6.3], Math.floor); // {4: 1, 6: 2}
  3. countBy(['one', 'two', 'three'], 'length'); // {3: 2, 5: 1}

countOccurrences(计数数组中某个值的出现次数)

计算数组中值的出现次数。

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

  1. const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a + 0), 0);
  1. // 示例
  2. countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3

deepFlatten(深度平铺数组)

深度平铺一个数组。

使用递归。 通过空数组([]) 使用 Array.concat() ,结合 展开运算符( … ) 来平铺数组。 递归平铺每个数组元素。

  1. const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));
  1. // 示例
  2. deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]

difference(数组比较)

返回两个数组之间的差异。

根据数组 b 创建一个 Set 对象,然后在数组 a 上使用 Array.filter() 方法,过滤出数组 b 中不包含的值。

  1. const difference = (a, b) => {
  2. const s = new Set(b);
  3. return a.filter(x => !s.has(x));
  4. };
  1. // 示例
  2. difference([1, 2, 3], [1, 2, 4]); // [3]

differenceBy(给定条件进行数组比较)

将给定函数应用于两个数组元素之后,返回两个数组之间的差异。

通过对 b 中的每个元素应用 fn 后创建一个 Set 对象,然后在数组 a 上使用 Array.filter() 和 fn ,只保留之前创建的集合中不包含的值。

  1. const differenceBy = (a, b, fn) => {
  2. const s = new Set(b.map(v => fn(v)));
  3. return a.filter(x => !s.has(fn(x)));
  4. };
  1. // 示例
  2. differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [1.2]
  3. differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], v => v.x); // [ { x: 2 } ]

differenceWith(通过比较函数比较两个数组的差异)

过滤掉比较函数不返回true的数组中的所有值。
使用 Array.filter() 和 Array.findIndex() 来查找合适的值。

  1. const differenceWith = (arr, val, comp) => arr.filter(a => val.findIndex(b => comp(a, b)) === -1);
  1. // 示例
  2. 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()从左侧删除指定数量的元素。

  1. const drop = (arr, n = 1) => arr.slice(n);
  1. // 示例
  2. drop([1, 2, 3]); // [2,3]
  3. drop([1, 2, 3], 2); // [3]
  4. drop([1, 2, 3], 42); // []

dropRight(从右边删除数组)

从右边边删除n个元素,并返回新数组。
使用 Array.slice()从右侧删除指定数量的元素。

  1. const dropRight = (arr, n = 1) => arr.slice(0, -n);
  1. // 示例
  2. dropRight([1, 2, 3]); // [1,2]
  3. dropRight([1, 2, 3], 2); // [1]
  4. dropRight([1, 2, 3], 42); // []

dropRightWhile(根据函数从右删除元素)

从数组末尾移除元素,直到传递的函数返回true。 返回数组中的其余元素。
循环访问数组,使用Array.slice()删除数组的最后一个元素,直到函数的返回值为true。 返回其余的元素。

  1. const dropRightWhile = (arr, func) => {
  2. while (arr.length > 0 && !func(arr[arr.length - 1])) arr = arr.slice(0, -1);
  3. return arr;
  4. };
  1. // 示例
  2. dropRightWhile([1, 2, 3, 4], n => n < 3); // [1, 2]

dropWhile(根据函数删除元素)

删除数组中的元素,直到传递的函数返回true。 返回数组中的其余元素。
循环访问数组,使用Array.slice()删除数组的第一个元素,直到函数的返回值为true。 返回其余的元素。

  1. const dropWhile = (arr, func) => {
  2. while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1);
  3. return arr;
  4. };
  1. // 示例
  2. dropWhile([1, 2, 3, 4], n => n >= 3); // [3,4]

everyNth( 获得数组中的每个第 n 个元素)

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

  1. const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1);
  1. // 示例
  2. everyNth([1, 2, 3, 4, 5, 6], 2); // [ 2, 4, 6 ]

filterNonUnique(数组去重)

过滤掉数组中的重复值。
使用 Array.filter() 滤除掉重复值,使数组仅包含唯一值。

  1. const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
  1. // 示例
  2. filterNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1,3,5]

findLast(获取符合条件的最后一个元素)

返回给定函数返回 true 的最后一个元素。
使用 Array.filter()移除 fn 返回 false的元素,Array.slice(-1)获取最后一个元素。

  1. const findLast = (arr, fn) => arr.filter(fn).slice(-1)[0];
  1. // 示例
  2. findLast([1, 2, 3, 4], n => n % 2 === 1); // 3

findLastIndex(获取符合条件的最后一个元素索引)

返回给定函数返回 true 的最后一个元素的索引。
使用 Array.map() 将每个元素映射到具有索引和值的数组。 使用Array.filter() 移除fn返回 false 的元素,Array.slice(-1) 获取最后一个元素。

  1. const findLastIndex = (arr, fn) =>
  2. arr
  3. .map((val, i) => [i, val])
  4. .filter(val => fn(val[1], val[0], arr))
  5. .slice(-1)[0][0];
  1. // 示例
  2. 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 (单层平铺) 的深度。

  1. const flatten = (arr, depth = 1) =>
  2. depth != 1
  3. ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v, depth - 1) : v), [])
  4. : arr.reduce((a, v) => a.concat(v), []);
  1. // 示例
  2. flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
  3. 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() 遍历这个反向数组。

  1. const forEachRight = (arr, callback) =>
  2. arr
  3. .slice(0)
  4. .reverse()
  5. .forEach(callback);
  1. // 示例
  2. forEachRight([1, 2, 3, 4], val => console.log(val)); // '4', '3', '2', '1'

groupBy(数组分组)

根据给定的函数对数组元素进行分组。
使用 Array.map() 将数组的值映射到函数或属性名称。使用 Array.reduce() 来创建一个对象,其中的 key 是从映射结果中产生。

  1. const groupBy = (arr, fn) =>
  2. arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val, i) => {
  3. acc[val] = (acc[val] || []).concat(arr[i]);
  4. return acc;
  5. }, {});
  1. // 示例
  2. groupBy([6.1, 4.2, 6.3], Math.floor); // {4: [4.2], 6: [6.1, 6.3]}
  3. groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']}

head(获取数组的第一个元素)

返回数组的第一个元素。
使用 arr[0] 返回传递数组的第一个元素。

  1. const head = arr => arr[0];
  1. // 示例
  2. head([1, 2, 3]); // 1

indexOfAll(返回指定元素的所有索引)

返回数组中所有 val 的索引。 如果 val 从不出现,则返回 [] 。
使用 Array.forEach() 循环元素和 Array.push() 来存储匹配元素的索引。 返回索引数组。

  1. const indexOfAll = (arr, val) => {
  2. const indices = [];
  3. arr.forEach((el, i) => el === val && indices.push(i));
  4. return indices;
  5. };
  1. // 示例
  2. indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
  3. indexOfAll([1, 2, 3], 4); // []

initial(排除数组中最后一个元素)

返回一个数组中除了最后一个元素以外的所有元素。
使用 arr.slice(0,-1) 返回排除了最后一个元素的数组。

  1. const initial = arr => arr.slice(0, -1);
  1. // 示例
  2. initial([1, 2, 3]); // [1,2]

initialize2DArray(初始化一个二维数组)

初始化一个给定行数和列数,及值的二维数组。
使用 Array.map() 生成 h 行,其中每个行都是一个长度为 w 的新数组。 如果未提供值 val ,则默认为 null。

  1. const initialize2DArray = (w, h, val = null) =>
  2. Array.from({ length: h }).map(() => Array.from({ length: w }).fill(val));
  1. // 示例
  2. 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 。

  1. const initializeArrayWithRange = (end, start = 0, step = 1) =>
  2. Array.from({ length: Math.ceil((end + 1 - start) / step) }).map((v, i) => i * step + start);
  1. // 示例
  2. initializeArrayWithRange(5); // [0,1,2,3,4,5]
  3. initializeArrayWithRange(7, 3); // [3,4,5,6,7]
  4. 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 。

  1. const initializeArrayWithRangeRight = (end, start = 0, step = 1) =>
  2. Array.from({ length: Math.ceil((end + 1 - start) / step) }).map(
  3. (v, i, arr) => (arr.length - i - 1) * step + start
  4. );
  1. // 示例
  2. initializeArrayWithRangeRight(5); // [5,4,3,2,1,0]
  3. initializeArrayWithRangeRight(7, 3); // [7,6,5,4,3]
  4. initializeArrayWithRangeRight(9, 0, 2); // [8,6,4,2,0]

initializeArrayWithValues(初始化特定范围和值的数组)

使用指定的值初始化和填充数组。
使用 Array(n) 创建所需长度的数组,使用 fill(v) 以填充所需的值。 你可以忽略 val ,使用默认值 0。

  1. const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);
  1. // 示例
  2. const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);

intersection(数组交集)

返回两个数组中都存在的元素列表。
根据数组 b 创建一个 Set 对象,然后在数组 a 上使用 Array.filter() 方法,只保留数组 b 中也包含的值。

  1. const intersection = (a, b) => {
  2. const s = new Set(b);
  3. return a.filter(x => s.has(x));
  4. };
  1. // 示例
  2. const intersection = (a, b) => {
  3. const s = new Set(b);
  4. return a.filter(x => s.has(x));
  5. };

intersectionBy(根据应用给定函数后求交集)

将给定函数应用于两个数组元素之后,返回两个数组中存在的元素列表。
通过将fn应用于b中的所有元素来创建一个Set,然后在a上使用Array.filter()来保留应用 fn 后包含在b中的值的元素。

  1. const intersectionBy = (a, b, fn) => {
  2. const s = new Set(b.map(x => fn(x)));
  3. return a.filter(x => s.has(fn(x)));
  4. };
  1. // 示例
  2. intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [2.1]

intersectionWith(根据条件求交集)

根据给定函数,求两个数组交集。
使用Array.filter()和 Array.findIndex()与给定的比较器结合确定相交值。

  1. const intersectionWith = (a, b, comp) => a.filter(x => b.findIndex(y => comp(x, y)) !== -1);
  1. // 示例
  2. 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 。

  1. const isSorted = arr => {
  2. const direction = arr[0] > arr[1] ? -1 : 1;
  3. for (let [i, val] of arr.entries())
  4. if (i === arr.length - 1) return direction;
  5. else if ((val - arr[i + 1]) * direction > 0) return 0;
  6. };
  1. //示例
  2. isSorted([0, 1, 2, 2]); // 1
  3. isSorted([4, 3, 2]); // -1
  4. isSorted([4, 3, 5]); // 0

join(将数组的所有元素拼接成一个字符串)

将数组的所有元素拼接成一个字符串并返回此字符串。 使用分隔符和结束分隔符。
使用 Array.reduce() 将元素拼接成一个字符串。 省略第二个参数 separator ,则默认使用分隔符’,’。 省略第三个参数 end ,默认使用与separator相同的值。

  1. const join = (arr, separator = ',', end = separator) =>
  2. arr.reduce(
  3. (acc, val, i) =>
  4. i == arr.length - 2
  5. ? acc + val + end
  6. : i == arr.length - 1 ? acc + val : acc + val + separator,
  7. ''
  8. );
  1. //示例
  2. join(['pen', 'pineapple', 'apple', 'pen'], ',', '&'); // "pen,pineapple,apple&pen"
  3. join(['pen', 'pineapple', 'apple', 'pen'], ','); // "pen,pineapple,apple,pen"
  4. join(['pen', 'pineapple', 'apple', 'pen']); // "pen,pineapple,apple,pen"

last(获取数组的最后一个元素)

返回数组中的最后一个元素。
使用 arr.length - 1 来计算给定数组的最后一个元素的索引并返回。

  1. const last = arr => arr[arr.length - 1];
  1. //示例
  2. last([1, 2, 3]); // 3

longestItem(获取最长元素)

获取任何数量的可迭代对象或具有 length 属性的对象,并返回最长的一个。
使用 Array.sort() 按 length 对所有参数进行排序,返回第一个(最长)元素。

  1. const longestItem = (...vals) => [...vals].sort((a, b) => b.length - a.length)[0];
  1. //示例
  2. longestItem('this', 'is', 'a', 'testcase'); // 'testcase'
  3. longestItem(...['a', 'ab', 'abc']); // 'abc'
  4. longestItem(...['a', 'ab', 'abc'], 'abcd'); // 'abcd'
  5. longestItem([1, 2, 3], [1, 2], [1, 2, 3, 4, 5]); // [1, 2, 3, 4, 5]
  6. longestItem([1, 2, 3], 'foobar'); // 'foobar'

mapObject(将数组的值映射到对象)

使用一个函数将数组的值映射到对象,其键值对中,原始值作为键,映射值作为值。
使用一个匿名的内部函数作用域来声明一个 undefined 的内存空间,使用闭包来存储返回值。 使用一个新的 Array 来存储带有函数映射的数组和一个逗号运算符来返回第二个步骤,而不需要从一个上下文移动到另一个上下文(由于闭包和操作顺序)。

  1. const mapObject = (arr, fn) =>
  2. (a => (
  3. (a = [arr, arr.map(fn)]), a[0].reduce((acc, val, ind) => ((acc[val] = a[1][ind]), acc), {})
  4. ))();
  1. //示例
  2. const squareIt = arr => mapObject(arr, a => a * a);
  3. squareIt([1, 2, 3]); // { 1: 1, 2: 4, 3: 9 }

maxN(返回数组中N个最大元素)

从提供的数组中返回 n 个最大元素。如果 n 大于或等于提供的数组长度,则返回原数组(按降序排列)。
结合使用Array.sort() 与展开操作符(…) ,创建一个数组的浅克隆,并按降序排列。 使用 Array.slice() 以获得指定的元素个数。 忽略第二个参数 n ,默认获取单个元素(以数组的形式)。

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

minN(返回数组中N个最小元素)

从提供的数组中返回 n 个最小元素。如果 n 大于或等于提供的数组长度,则返回原数组(按降序排列)。
结合使用Array.sort() 与展开操作符(…) ,创建一个数组的浅克隆,并按降序排列。 使用 Array.slice() 以获得指定的元素个数。 忽略第二个参数 n ,默认获取单个元素(以数组的形式)。

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

nthElement(获取数组的第N个元素)

返回数组的第n个元素。
使用 Array.slice() 获取数组的第 n 个元素。如果索引超出范围,则返回 [] 。省略第二个参数 n ,将得到数组的第一个元素。

  1. const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0];
  1. //示例
  2. nthElement(['a', 'b', 'c'], 1); // 'b'
  3. nthElement(['a', 'b', 'b'], -3); // 'a'

partition(数组元素分组)

根据所提供的函数对每个元素进行迭代,将这些元素分成两个数组。
使用 Array.reduce() 创建两个数组的数组。 使用 Array.push() 将 fn 返回为 true 的元素添加到第一个数组,而 fn 返回 false 的元素到第二个元素。

  1. const partition = (arr, fn) =>
  2. arr.reduce(
  3. (acc, val, i, arr) => {
  4. acc[fn(val, i, arr) ? 0 : 1].push(val);
  5. return acc;
  6. },
  7. [[], []]
  8. );
  1. //示例
  2. const users = [{ user: 'barney', age: 36, active: false }, { user: 'fred', age: 40, active: true }];
  3. 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 值重新填充数组。

  1. const pull = (arr, ...args) => {
  2. let argState = Array.isArray(args[0]) ? args[0] : args;
  3. let pulled = arr.filter((v, i) => !argState.includes(v));
  4. arr.length = 0;
  5. pulled.forEach(v => arr.push(v));
  6. };
  1. //示例
  2. let myArray = ['a', 'b', 'c', 'a', 'b', 'c'];
  3. pull(myArray, 'a', 'c'); // myArray = [ 'b', 'b' ]

pullAtIndex(删除数组中指定索引的值)

改变原始数组,过滤掉指定索引的值。
使用 Array.filter() 和 Array.includes() 来剔除指定的值。使用 Array.length = 0 将数组中的长度重置为零, 并且通过 Array.push() 只使用 pulled 值重新填充数组。使用 Array.push() 来跟踪 pulled 值。

  1. const pullAtIndex = (arr, pullArr) => {
  2. let removed = [];
  3. let pulled = arr
  4. .map((v, i) => (pullArr.includes(i) ? removed.push(v) : v))
  5. .filter((v, i) => !pullArr.includes(i));
  6. arr.length = 0;
  7. pulled.forEach(v => arr.push(v));
  8. return removed;
  9. };
  1. //示例
  2. let myArray = ['a', 'b', 'c', 'd'];
  3. 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 值。

  1. const pullAtValue = (arr, pullArr) => {
  2. let removed = [],
  3. pushToRemove = arr.forEach((v, i) => (pullArr.includes(v) ? removed.push(v) : v)),
  4. mutateTo = arr.filter((v, i) => !pullArr.includes(v));
  5. arr.length = 0;
  6. mutateTo.forEach(v => arr.push(v));
  7. return removed;
  8. };
  1. //示例
  2. let myArray = ['a', 'b', 'c', 'd'];
  3. 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()只用拉取的值重新填充数组。

  1. const pullBy = (arr, ...args) => {
  2. const length = args.length;
  3. let fn = length > 1 ? args[length - 1] : undefined;
  4. fn = typeof fn == 'function' ? (args.pop(), fn) : undefined;
  5. let argState = (Array.isArray(args[0]) ? args[0] : args).map(val => fn(val));
  6. let pulled = arr.filter((v, i) => !argState.includes(fn(v)));
  7. arr.length = 0;
  8. pulled.forEach(v => arr.push(v));
  9. };
  1. //示例
  2. var myArray = [{ x: 1 }, { x: 2 }, { x: 3 }, { x: 1 }];
  3. pullBy(myArray, [{ x: 1 }, { x: 3 }], o => o.x); // myArray = [{ x: 2 }]

未完待续…

如非特别注明,文章皆为原创。

转载请注明出处: https://www.liayal.com/article/5a7177acfb1bf64cecfdee9e

你不想说点啥么?
😀😃😄😁😆😅😂🤣☺️😊😇🙂🙃😉😌😍😘😗😙😚😋😜😝😛🤑🤗🤓😎🤡🤠😏😒😞😔😟😕🙁☹️😣😖😫😩😤😠😡😶😐😑😯😦😧😮😲😵😳😱😨😰😢😥🤤😭😓😪😴🙄🤔🤥😬🤐🤢🤧😷🤒🤕😈👿👹👺💩👻💀☠️👽👾🤖🎃😺😸😹😻😼😽🙀😿😾👐👐🏻👐🏼👐🏽👐🏾👐🏿🙌🙌🏻🙌🏼🙌🏽🙌🏾🙌🏿👏👏🏻👏🏼👏🏽👏🏾👏🏿🙏🙏🏻🙏🏼🙏🏽🙏🏾🙏🏿🤝👍👍🏻👍🏼👍🏽👍🏾👍🏿👎👎🏻👎🏼👎🏽👎🏾👎🏿👊👊🏻👊🏼👊🏽👊🏾👊🏿✊🏻✊🏼✊🏽✊🏾✊🏿

评论

~ 评论还没有,沙发可以有 O(∩_∩)O~