日常开发中,数组对于我们来说是经常使用到的,由此这里给大家分享49个关于Array实用的一行Javascript与typescript代码大全,内容很多,建议收藏阅读!
将值转换为数组
JavaScript 版本
const castArray = (value) => (Array.isArray(value) ? value : [value]);
TypeScript 版本
const castArray = <T,_>(value: T | T[]): T[] => (Array.isArray(value) ? value : [value]);
Demo
castArray(1); // [1]
castArray([1, 2, 3]); // [1, 2, 3]
检查数组是否为空
JavaScript 版本
// `arr` is an array
const isEmpty = (arr) => !Array.isArray(arr) || arr.length === 0;
TypeScript 版本
const isEmpty = <T,_>(arr: T[]): boolean => !Array.isArray(arr) || arr.length === 0;
Demo
isEmpty([]); // true
isEmpty([1, 2, 3]); // false
克隆一个数组
JavaScript 版本
// `arr` is an array
const clone = (arr) => arr.slice(0);
// Or
const clone = (arr) => [...arr];
// Or
const clone = (arr) => Array.from(arr);
// Or
const clone = (arr) => arr.map((x) => x);
// Or
const clone = (arr) => JSON.parse(JSON.stringify(arr));
// Or
const clone = (arr) => arr.concat([]);
TypeScript 版本
// `arr` is an array
const clone = <T,_>(arr: T[]): T[] => arr.slice(0);
// Or
const clone = <T,_>(arr: T[]): T[] => [...arr];
// Or
const clone = <T,_>(arr: T[]): T[] => Array.from(arr);
// Or
const clone = <T,_>(arr: T[]): T[] => arr.map((x) => x);
// Or
const clone = <T,_>(arr: T[]): T[] => JSON.parse(JSON.stringify(arr));
// Or
const clone = <T,_>(arr: T[]): T[] => arr.concat([]);
无论顺序如何比较两个数组
JavaScript 版本
// `a` and `b` are arrays
const isEqual = (a, b) => JSON.stringify(a.sort()) === JSON.stringify(b.sort());
TypeScript 版本
const isEqual = <T,_>(a: T[], b: T[]): boolean => JSON.stringify(a.sort()) === JSON.stringify(b.sort());
Demo
isEqual([1, 2, 3], [1, 2, 3]); // true
isEqual([1, 2, 3], [1, 3, 2]); // true
isEqual([1, 2, 3], [1, '2', 3]); // false
比较两个数组
JavaScript 版本
// `a` and `b` are arrays
const isEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
// Or
const isEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
TypeScript 版本
const isEqual = <T,_>(a: T[], b: T[]): boolean => JSON.stringify(a) === JSON.stringify(b);
// Or
const isEqual = <T,_>(a: T[], b: T[]): boolean => a.length === b.length && a.every((v, i) => v === b[i]);
Demo
isEqual([1, 2, 3], [1, 2, 3]); // true
isEqual([1, 2, 3], [1, '2', 3]); // false
将对象数组转换为单个对象
JavaScript 版本
const toObject = (arr, key) => arr.reduce((a, b) => ({ ...a, [b[key]]: b }), {});
// Or
const toObject = (arr, key) => Object.fromEntries(arr.map((it) => [it[key], it]));
TypeScript 版本
const toObject = <T extends Record<string, any>, K extends keyof T>(arr: T[], key: K): Record<string, T> => (
arr.reduce((a, b) => ({ ...a, [b[key]]: b }), {})
);
const toObject = <T extends Record<string, any>, K extends keyof T>(arr: T[], key: K): Record<string, T> => (
Object.fromEntries(arr.map((it) => [it[key], it]))
);
Demo
toObject(
[
{ id: '1', name: 'Alpha', gender: 'Male' },
{ id: '2', name: 'Bravo', gender: 'Male' },
{ id: '3', name: 'Charlie', gender: 'Female' },
],
'id'
);
/*
{
'1': { id: '1', name: 'Alpha', gender: 'Male' },
'2': { id: '2', name: 'Bravo', gender: 'Male' },
'3': { id: '3', name: 'Charlie', gender: 'Female' },
}
*/
将字符串数组转换为数字
JavaScript 版本
const toNumbers = (arr) => arr.map(Number);
// Or
const toNumbers = (arr) => arr.map((x) => +x);
TypeScript 版本
const toNumbers = (arr: string[]): number[] => arr.map(Number);
// Or
const toNumbers = (arr: string[]): number[] => arr.map((x) => +x);
Demo
toNumbers(['2', '3', '4']); // [2, 3, 4]
按对象数组的属性计数
JavaScript 版本
const countBy = (arr, prop) => arr.reduce((prev, curr) => ((prev[curr[prop]] = ++prev[curr[prop]] || 1), prev), {});
TypeScript 版本
const countBy = <T extends Record<string, string>, K extends keyof T>(arr: T[], prop: K): Record<string, number> => (
arr.reduce((prev, curr) => ((prev[curr[prop]] = ++prev[curr[prop]] || 1), prev), {} as Record<string, number>)
);
Demo
countBy(
[
{ branch: 'audi', model: 'q8', year: '2019' },
{ branch: 'audi', model: 'rs7', year: '2020' },
{ branch: 'ford', model: 'mustang', year: '2019' },
{ branch: 'ford', model: 'explorer', year: '2020' },
{ branch: 'bmw', model: 'x7', year: '2020' },
],
'branch'
);
// { 'audi': 2, 'ford': 2, 'bmw': 1 }
计算数组中某个值的出现次数
JavaScript 版本
const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);
// Or
const countOccurrences = (arr, val) => arr.filter((item) => item === val).length;
TypeScript 版本
const countOccurrences = <T,_>(arr: T[], val: T): number => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);
// Or
const countOccurrences = <T,_>(arr: T[], val: T): number => arr.filter((item) => item === val).length;
Demo
countOccurrences([2, 1, 3, 3, 2, 3], 2); // 2
countOccurrences(['a', 'b', 'a', 'c', 'a', 'b'], 'a'); // 3
计算数组元素的出现次数
JavaScript 版本
const countOccurrences = (arr) => arr.reduce((prev, curr) => ((prev[curr] = ++prev[curr] || 1), prev), {});
TypeScript 版本
const countOccurrences = <T extends string | number,>(arr: T[]): Record<T, number> => (
arr.reduce((prev, curr) => ((prev[curr] = ++prev[curr] || 1), prev), {}as Record<T, number>)
);
Demo
countOccurrences([2, 1, 3, 3, 2, 3]); // { '1': 1, '2': 2, '3': 3 }
countOccurrences(['a', 'b', 'a', 'c', 'a', 'b']); // { 'a': 3, 'b': 2, 'c': 1 }
创建一个累积和的数组
const accumulate = (arr) =>
arr.map(
(
(sum) => (value) =>
(sum += value)
)(0)
);
// Or
const accumulate = (arr) => arr.reduce((a, b, i) => (i === 0 ? [b] : [...a, b + a[i - 1]]), [0]);
TypeScript 版本
const accumulate = (arr: number[]): number[] =>
arr.map(
(
(sum) => (value: number) =>
(sum += value)
)(0)
);
// Or
const accumulate = (arr: number[]): number[] => arr.reduce((a, b, i) => (i === 0 ? [b] : [...a, b + a[i - 1]]), [0]);
Demo
accumulate([1, 2, 3, 4]); // [1, 3, 6, 10]
// 1 = 1
// 1 + 2 = 3
// 1 + 2 + 3 = 6
// 1 + 2 + 3 + 4 = 10
创建给定范围内的数字数组
const range = (min, max) => [...Array(max - min + 1).keys()].map((i) => i + min);
// Or
const range = (min, max) =>
Array(max - min + 1)
.fill(0)
.map((_, i) => min + i);
// Or
const range = (min, max) => Array.from({ length: max - min + 1 }, (_, i) => min + i);
TypeScript 版本
const range = (min: number, max: number): number[] => [...Array(max - min + 1).keys()].map((i) => i + min);
// Or
const range = (min: number, max: number): number[] =>
Array(max - min + 1)
.fill(0)
.map((_, i) => min + i);
// Or
const range = (min: number, max: number): number[] => Array.from({ length: max - min + 1 }, (_, i) => min + i);
Demo
range(5, 10); // [5, 6, 7, 8, 9, 10]
创建笛卡尔积
const cartesian = (...sets) => sets.reduce((acc, set) => acc.flatMap((x) => set.map((y) => [...x, y])), [[]]);
Demo
cartesian([1, 2], [3, 4]); // [ [1, 3], [1, 4], [2, 3], [2, 4] ]
/*
3 4
---------------
1 | [1, 3] [1, 4]
|
2 | [2, 3] [2, 4]
*/
清空数组
JavaScript 版本
const empty = (arr) => (arr.length = 0);
// Or
arr = [];
TypeScript 版本
const empty = <T,_>(arr: T[]) => (arr.length = 0);
// Or
arr = [];
从数组中找到最接近的数字
JavaScript 版本
// Find the number from `arr` which is closest to `n`
const closest = (arr, n) => arr.reduce((prev, curr) => (Math.abs(curr - n) < Math.abs(prev - n) ? curr : prev));
// Or
const closest = (arr, n) => arr.sort((a, b) => Math.abs(a - n) - Math.abs(b - n))[0];
TypeScript 版本
const closest = (arr: number[], n: number): number => arr.reduce((prev, curr) => (Math.abs(curr - n) < Math.abs(prev - n) ? curr : prev));
// Or
const closest = (arr: number[], n: number): number => arr.sort((a, b) => Math.abs(a - n) - Math.abs(b - n))[0];
Demo
closest([29, 87, 8, 78, 97, 20, 75, 33, 24, 17], 50); // 33
查找数组最后一个匹配项的索引
JavaScript 版本
const lastIndex = (arr, predicate) => arr.reduce((prev, curr, index) => (predicate(curr) ? index : prev), -1);
// Or
const lastIndex = (arr, predicate) => arr.map((item) => predicate(item)).lastIndexOf(true);
TypeScript 版本
const lastIndex = <T,_>(arr: T[], predicate: (a: T) => boolean): number => arr.reduce((prev, curr, index) => (predicate(curr) ? index : prev), -1);
// Or
const lastIndex = <T,_>(arr: T[], predicate: (a: T) => boolean): number => arr.map((item) => predicate(item)).lastIndexOf(true);
Demo
lastIndex([1, 3, 5, 7, 9, 2, 4, 6, 8], (i) => i % 2 === 1); // 4
lastIndex([1, 3, 5, 7, 9, 8, 6, 4, 2], (i) => i > 6); // 5
查找数组最大项的索引
JavaScript 版本
const indexOfMax = (arr) => arr.reduce((prev, curr, i, a) => (curr > a[prev] ? i : prev), 0);
TypeScript 版本
const indexOfMax = (arr: number[]): number => arr.reduce((prev, curr, i, a) => (curr > a[prev] ? i : prev), 0);
Demo
indexOfMax([1, 3, 9, 7, 5]); // 2
indexOfMax([1, 3, 7, 7, 5]); // 2
查找数组中最小项的索引
JavaScript 版本
const indexOfMin = (arr) => arr.reduce((prev, curr, i, a) => (curr < a[prev] ? i : prev), 0);
TypeScript 版本
const indexOfMin = (arr: number[]): number => arr.reduce((prev, curr, i, a) => (curr < a[prev] ? i : prev), 0);
Demo
indexOfMin([6, 4, 8, 2, 10]); // 3
indexOfMin([6, 4, 2, 2, 10]); // 2
查找数组中最长字符串的长度
JavaScript 版本
const findLongest = (words) => Math.max(...words.map((el) => el.length));
TypeScript 版本
const findLongest = (words: string[]): number => Math.max(...words.map((el) => el.length));
Demo
findLongest(['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']); // 6
通过给定的键查找数组的最大项
JavaScript 版本
const maxBy = (arr, key) => arr.reduce((a, b) => (a[key] >= b[key] ? a : b), {});
TypeScript 版本
const maxBy = <T extends Record<string, any>, K extends keyof T>(arr: T[], key: K): T => (
arr.reduce((a, b) => (a[key] >= b[key] ? a : b), {} as T)
);
Demo
const people = [
{ name: 'Bar', age: 24 },
{ name: 'Baz', age: 32 },
{ name: 'Foo', age: 42 },
{ name: 'Fuzz', age: 36 },
];
maxBy(people, 'age'); // { name: 'Foo', age: 42 }
查找数组的最大项
JavaScript 版本
const max = (arr) => Math.max(...arr);
TypeScript 版本
const max = (arr: number[]): number => Math.max(...arr);
通过给定的键查找数组的最小项
JavaScript 版本
const minBy = (arr, key) => arr.reduce((a, b) => (a[key] < b[key] ? a : b), {});
TypeScript 版本
const minBy = <T extends Record<string, any>, K extends keyof T>(arr: T[], key: K): T => (
arr.reduce((a, b) => (a[key] < b[key] ? a : b), {} as T)
);
Demo
const people = [
{ name: 'Bar', age: 24 },
{ name: 'Baz', age: 32 },
{ name: 'Foo', age: 42 },
{ name: 'Fuzz', age: 36 },
];
minBy(people, 'age'); // { name: 'Bar', age: 24 }
查找数组的最小项
JavaScript 版本
const min = (arr) => Math.min(...arr);
TypeScript 版本
const min = (arr: number[]): number => Math.min(...arr);
展平一个数组
JavaScript 版本
const flat = (arr) =>
[].concat.apply(
[],
arr.map((a) => (Array.isArray(a) ? flat(a) : a))
);
// Or
const flat = (arr) => arr.reduce((a, b) => (Array.isArray(b) ? [...a, ...flat(b)] : [...a, b]), []);
// Or
// See the browser compatibility at https://caniuse.com/#feat=array-flat
const flat = (arr) => arr.flat();
Demo
flat(['cat', ['lion', 'tiger']]); // ['cat', 'lion', 'tiger']
生成字母字符数组
JavaScript 版本
const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
// Or
const alphabet = [...'abcdefghijklmnopqrstuvwxyz'];
// Or
const alphabet = Array(26)
.fill(0)
.map((_, i) => String.fromCharCode(i + 97));
// Or
const alphabet = [...Array(26).keys()].map((i) => String.fromCharCode(i + 97));
// Or
const alphabet = [...Array(26)].map((_, i) => (i + 10).toString(36));
// Or
const alphabet = String.fromCharCode(
...' '
.repeat(26)
.split('')
.map((_, i) => i + 97)
).split('');
TypeScript 版本
const alphabet: string[] = 'abcdefghijklmnopqrstuvwxyz'.split('');
// Or
const alphabet: string[] = [...'abcdefghijklmnopqrstuvwxyz'];
// Or
const alphabet: string[] = Array(26)
.fill(0)
.map((_, i) => String.fromCharCode(i + 97));
// Or
const alphabet: string[] = [...Array(26).keys()].map((i) => String.fromCharCode(i + 97));
// Or
const alphabet: string[] = [...Array(26)].map((_, i) => (i + 10).toString(36));
// Or
const alphabet: string[] = String.fromCharCode(
...' '
.repeat(26)
.split('')
.map((_, i) => i + 97)
).split('');
获取所有连续元素的数组
JavaScript 版本
const getConsecutiveArrays = (arr, size) => (size > arr.length ? [] : arr.slice(size - 1).map((_, i) => arr.slice(i, size + i)));
TypeScript 版本
const getConsecutiveArrays = <T,_>(arr: T[], size: number): T[][] => (size > arr.length ? [] : arr.slice(size - 1).map((_, i) => arr.slice(i, size + i)));
Demo
getConsecutiveArrays([1, 2, 3, 4, 5], 2); // [[1, 2], [2, 3], [3, 4], [4, 5]]
getConsecutiveArrays([1, 2, 3, 4, 5], 3); // [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
getConsecutiveArrays([1, 2, 3, 4, 5], 6); // []
获取数组的所有第 n 项
JavaScript 版本
const getNthItems = (arr, nth) => arr.filter((_, i) => i % nth === nth - 1);
TypeScript 版本
const getNthItems = <T,_>(arr: T[], nth: number): T[] => arr.filter((_, i) => i % nth === nth - 1);
Demo
getNthItems([1, 2, 3, 4, 5, 6, 7, 8, 9], 2); // [2, 4, 6, 8]
getNthItems([1, 2, 3, 4, 5, 6, 7, 8, 9], 3); // [3, 6, 9]
获取数组的所有子集
JavaScript 版本
const getSubsets = (arr) => arr.reduce((prev, curr) => prev.concat(prev.map((k) => k.concat(curr))), [[]]);
TypeScript 版本
const getSubsets = <T,>(arr: T[]): T[][] => (
arr.reduce((prev, curr) => prev.concat(prev.map((k) => k.concat(curr))), [[]] as T[][])
);
Demo
getSubsets([1, 2]); // [[], [1], [2], [1, 2]]
getSubsets([1, 2, 3]); // [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
获取数组中某个值的索引
JavaScript 版本
const indices = (arr, value) => arr.reduce((acc, v, i) => (v === value ? [...acc, i] : acc), []);
// Or
const indices = (arr, value) => arr.map((v, i) => (v === value ? i : false)).filter(Boolean);
TypeScript 版本
const indices = <T,>(arr: T[], value: T): number[] => (
arr.reduce((acc, v, i) => (v === value ? [...acc, i] : acc), [] as number[])
);
// Or
const indices = <T,>(arr: T[], value: T): number[] => (
arr.map((v, i) => (v === value ? i : false)).filter(Boolean) as number[]
);
Demo
indices(['h', 'e', 'l', 'l', 'o'], 'l'); // [2, 3]
indices(['h', 'e', 'l', 'l', 'o'], 'w'); // []
获取数组的平均值
JavaScript 版本
const average = (arr) => arr.reduce((a, b) => a + b, 0) / arr.length;
TypeScript 版本
const average = (arr: number[]): number => arr.reduce((a, b) => a + b, 0) / arr.length;
获取数组的交集
JavaScript 版本
const getIntersection = (a, ...arr) => [...new Set(a)].filter((v) => arr.every((b) => b.includes(v)));
TypeScript 版本
const getIntersection = <T,_>(a: T[], ...arr: T[][]): T[] => [...new Set(a)].filter((v) => arr.every((b) => b.includes(v)));
Demo
getIntersection([1, 2, 3], [2, 3, 4, 5]); // [2, 3]
getIntersection([1, 2, 3], [2, 3, 4, 5], [1, 3, 5]); // [3]
获取数字数组的排名
JavaScript 版本
const ranking = (arr) => arr.map((x, y, z) => z.filter((w) => w > x).length + 1);
TypeScript 版本
const ranking = (arr: number[]): number[] => arr.map((x, y, z) => z.filter((w) => w > x).length + 1);
Demo
ranking([80, 65, 90, 50]); // [2, 3, 1, 4]
ranking([80, 80, 70, 50]); // [1, 1, 3, 4]
ranking([80, 80, 80, 50]); // [1, 1, 1, 4]
获取一组数字的总和
JavaScript 版本
const sum = (arr) => arr.reduce((a, b) => a + b, 0);
TypeScript 版本
const sum = (arr: number[]): number => arr.reduce((a, b) => a + b, 0);
获取数组的唯一值
JavaScript 版本
const unique = (arr) => [...new Set(arr)];
// Or
const unique = (arr) => arr.filter((el, i, array) => array.indexOf(el) === i);
// Or
const unique = (arr) => arr.reduce((acc, el) => (acc.includes(el) ? acc : [...acc, el]), []);
TypeScript 版本
const unique = <T,>(arr: T[]): T[] => [...new Set(arr)];
// Or
const unique = <T,>(arr: T[]): T[] => arr.filter((el, i, array) => array.indexOf(el) === i);
// Or
const unique = <T,>(arr: T[]): T[] => arr.reduce((acc, el) => (acc.includes(el) ? acc : [...acc, el]), [] as T[]);
获取数组的并集
JavaScript 版本
const union = (...arr) => [...new Set(arr.flat())];
TypeScript 版本
const union = <T,_>(...arr: T[][]): T[] => [...new Set(arr.flat())];
Demo
union([1, 2], [2, 3], [3]); // [1, 2, 3]
按键对对象数组进行分组
JavaScript 版本
const groupBy = (arr, key) => arr.reduce((acc, item) => ((acc[item[key]] = [...(acc[item[key]] || []), item]), acc), {});
TypeScript 版本
const groupBy = <T extends Record<string, any>, K extends keyof T>(arr: T[], key: K): Record<string, T[]> => (
arr.reduce((acc, item) => ((acc[item[key]] = [...(acc[item[key]] || []), item]), acc), {} as Record<string, T[]>)
);
Demo
groupBy(
[
{ branch: 'audi', model: 'q8', year: '2019' },
{ branch: 'audi', model: 'rs7', year: '2020' },
{ branch: 'ford', model: 'mustang', year: '2019' },
{ branch: 'ford', model: 'explorer', year: '2020' },
{ branch: 'bmw', model: 'x7', year: '2020' },
],
'branch'
);
/*
{
audi: [
{ branch: 'audi', model: 'q8', year: '2019' },
{ branch: 'audi', model: 'rs7', year: '2020' }
],
bmw: [
{ branch: 'bmw', model: 'x7', year: '2020' }
],
ford: [
{ branch: 'ford', model: 'mustang', year: '2019' },
{ branch: 'ford', model: 'explorer', year: '2020' }
],
}
*/
合并两个数组
JavaScript 版本
// Merge but don't remove the duplications
const merge = (a, b) => a.concat(b);
// Or
const merge = (a, b) => [...a, ...b];
// Merge and remove the duplications
const merge = (a, b) => [...new Set(a.concat(b))];
// Or
const merge = (a, b) => [...new Set([...a, ...b])];
TypeScript 版本
// Merge but don't remove the duplications
const merge = <T,_>(a: T[], b: T[]): T[] => a.concat(b);
// Or
const merge = <T,_>(a: T[], b: T[]): T[] => [...a, ...b];
// Merge and remove the duplications
const merge = <T,_>(a: T[], b: T[]): T[] => [...new Set(a.concat(b))];
// Or
const merge = <T,_>(a: T[], b: T[]): T[] => [...new Set([...a, ...b])];
根据条件对数组进行分区
JavaScript 版本
const partition = (arr, criteria) => arr.reduce((acc, i) => (acc[criteria(i) ? 0 : 1].push(i), acc), [[], []]);
TypeScript 版本
const partition = <T,_>(arr: T[], criteria: (a: T) => boolean): T[][] => arr.reduce((acc, i) => (acc[criteria(i) ? 0 : 1].push(i), acc), [[], []]);
Demo
partition([1, 2, 3, 4, 5], (n) => n % 2); // [[1, 3, 5], [2, 4]]
删除数组中的重复值
JavaScript 版本
const removeDuplicate = (arr) => arr.filter((i) => arr.indexOf(i) === arr.lastIndexOf(i));
TypeScript 版本
const removeDuplicate = <T,_>(arr: T[]): T[] => arr.filter((i) => arr.indexOf(i) === arr.lastIndexOf(i));
Demo
removeDuplicate(['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']); // ['h', 'e', 'w', 'r', 'd']
从数组中删除假值
JavaScript 版本
const removeFalsy = (arr) => arr.filter(Boolean);
TypeScript 版本
const removeFalsy = <T,_>(arr: T[]): T[] => arr.filter(Boolean);
Demo
removeFalsy([0, 'a string', '', NaN, true, 5, undefined, 'another string', false]);
// ['a string', true, 5, 'another string']
重复数组
JavaScript 版本
// `arr` is an array
const repeat = (arr, n) => [].concat(...Array(n).fill(arr));
// Or
const repeat = (arr, n) => Array(n).fill(arr).flat();
// Or
const repeat = (arr, n) =>
Array(arr.length * n)
.fill(0)
.map((_, i) => arr[i % arr.length]);
// Or
const repeat = (arr, n) => Array.from({ length: arr.length * n }, (_, i) => arr[i % arr.length]);
TypeScript 版本
const repeat = <T,_>(arr: T[], n: number): T[] => [].concat(...Array(n).fill(arr));
// Or
const repeat = <T,_>(arr: T[], n: number): T[] => Array(n).fill(arr).flat();
// Or
const repeat = <T,_>(arr: T[], n: number): T[] =>
Array(arr.length * n)
.fill(0)
.map((_, i) => arr[i % arr.length]);
// Or
const repeat = <T,_>(arr: T[], n: number): T[] => Array.from({ length: arr.length * n }, (_, i) => arr[i % arr.length]);
Demo
repeat([1, 2, 3], 3); // [1, 2, 3, 1, 2, 3, 1, 2, 3]
打乱数组
JavaScript 版本
const shuffle = (arr) =>
arr
.map((a) => ({ sort: Math.random(), value: a }))
.sort((a, b) => a.sort - b.sort)
.map((a) => a.value);
// Or
const shuffle = (arr) => arr.sort(() => 0.5 - Math.random());
TypeScript 版本
const shuffle = <T,_>(arr: T[]): T[] =>
arr
.map((a) => ({ sort: Math.random(), value: a }))
.sort((a, b) => a.sort - b.sort)
.map((a) => a.value);
// Or
const shuffle = <T,_>(arr: T[]): T[] => arr.sort(() => 0.5 - Math.random());
Demo
shuffle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); // [9, 1, 10, 6, 8, 5, 2, 3, 7, 4]
按给定键对项目数组进行排序
JavaScript 版本
const sortBy = (arr, k) => arr.concat().sort((a, b) => (a[k] > b[k] ? 1 : a[k] < b[k] ? -1 : 0));
TypeScript 版本
const sortBy = <T extends Record<string, any>, K extends keyof T>(arr: T[], k: K): T[] => (
arr.concat().sort((a, b) => (a[k] > b[k] ? 1 : a[k] < b[k] ? -1 : 0))
);
Demo
const people = [
{ name: 'Foo', age: 42 },
{ name: 'Bar', age: 24 },
{ name: 'Fuzz', age: 36 },
{ name: 'Baz', age: 32 },
];
sortBy(people, 'age');
// [
// { name: 'Bar', age: 24 },
// { name: 'Baz', age: 32 },
// { name: 'Fuzz', age: 36 },
// { name: 'Foo', age: 42 },
// ]
对数字数组进行排序
JavaScript 版本
const sort = (arr) => arr.sort((a, b) => a - b);
TypeScript 版本
const sort = (arr: number[]): number[] => arr.sort((a, b) => a - b);
Demo
sort([1, 5, 2, 4, 3]); // [1, 2, 3, 4, 5]
将数组拆分为块
JavaScript 版本
const chunk = (arr, size) => arr.reduce((acc, e, i) => (i % size ? acc[acc.length - 1].push(e) : acc.push([e]), acc), []);
TypeScript 版本
const chunk = <T,>(arr: T[], size: number): T[][] => (
arr.reduce((acc, e, i) => (i % size ? acc[acc.length - 1].push(e) : acc.push([e]), acc), [] as T[][])
);
Demo
chunk([1, 2, 3, 4, 5, 6, 7, 8], 3); // [[1, 2, 3], [4, 5, 6], [7, 8]]
chunk([1, 2, 3, 4, 5, 6, 7, 8], 4); // [[1, 2, 3, 4], [5, 6, 7, 8]]
交换矩阵的行和列
JavaScript 版本
const transpose = (matrix) => matrix[0].map((col, i) => matrix.map((row) => row[i]));
// Or
const transpose = (matrix) => matrix[0].map((col, c) => matrix.map((row, r) => matrix[r][c]));
// Or
const transpose = (matrix) => matrix.reduce((prev, next) => next.map((item, i) => (prev[i] || []).concat(next[i])), []);
TypeScript 版本
const transpose = <T,>(matrix: T[][]): T[][] => matrix[0].map((col, i) => matrix.map((row) => row[i]));
// Or
const transpose = <T,>(matrix: T[][]): T[][] => matrix[0].map((col, c) => matrix.map((row, r) => matrix[r][c]));
// Or
const transpose = <T,>(matrix: T[][]): T[][] => (
matrix.reduce((prev, next) => next.map((item, i) => (prev[i] || []).concat(next[i])), [] as T[][])
);
Demo
transpose([
// [
[1, 2, 3], // [1, 4, 7],
[4, 5, 6], // [2, 5, 8],
[7, 8, 9], // [3, 6, 9],
]); // ]
交换两个数组项
JavaScript 版本
// `i` must be less than `j`
const swapItems = (a, i, j) => (a[i] && a[j] && [...a.slice(0, i), a[j], ...a.slice(i + 1, j), a[i], ...a.slice(j + 1)]) || a;
TypeScript 版本
const swapItems = <T,_>(a: T[], i: number, j: number): T[] => (a[i] && a[j] && [...a.slice(0, i), a[j], ...a.slice(i + 1, j), a[i], ...a.slice(j + 1)]) || a;
Demo
swapItems([1, 2, 3, 4, 5], 1, 4); // [1, 5, 3, 4, 2]
解压缩数组数组
JavaScript 版本
const unzip = (arr) =>
arr.reduce(
(acc, c) => (c.forEach((v, i) => acc[i].push(v)), acc),
Array.from({ length: Math.max(...arr.map((a) => a.length)) }, (_) => [])
);
Demo
unzip([
['a', 1],
['b', 2],
['c', 3],
['d', 4],
['e', 5],
]); // [['a', 'b', 'c', 'd', 'e'], [1, 2, 3, 4, 5]]
/*
a 1
b 2
c 3
d 4
e 5
*/
压缩多个数组
JavaScript 版本
const zip = (...arr) => Array.from({ length: Math.max(...arr.map((a) => a.length)) }, (_, i) => arr.map((a) => a[i]));
Demo
zip(['a', 'b', 'c', 'd', 'e'], [1, 2, 3, 4, 5]); // [['a', 1], ['b', 2], ['c', 3], ['d', 4], ['e', 5]]
/*
Does it look like a zipper?
a 1
b 2
c 3
d 4
e 5
*/
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/10083.html