Maison > Article > interface Web > 25 utilisations avancées de la réduction des matrices à connaître
Reduce, en tant que l'une des nouvelles méthodes de tableau régulières d'ES5, est une méthode puissante. Cet article vous présentera 25 utilisations avancées de la réduction de tableau.
reduce
est l'une des nouvelles méthodes de tableau régulières dans ES5. Par rapport à forEach
, filter
et map
, elle semble être quelque peu ignorée dans l'utilisation réelle, je trouve que les gens autour de moi l'utilisent rarement, ce qui conduit à une utilisation progressive. déclin de cette méthode puissante enterrée.
Si vous l'utilisez fréquemmentreduce
, comment pourriez-vous l'abandonner ? Il me reste à le sortir de la poussière, à l'essuyer et à vous proposer ses utilisations avancées. Une méthode aussi utile ne devrait pas être enterrée par le public.
Ce qui suit est une brève explication de la syntaxe de reduce
Pour plus de détails, veuillez consulter les instructions pertinentes de MDN
reduce().
array.reduce((t, v, i, a) => {}, initValue)
必选
可选
t
)必选
v
)必选
i
)可选
a
)可选
t
commence le parcours avec le premier élément du tableau comme valeur initiale t
v
à v
, termine la boucle, revient à t
t
t
L'essence est d'appliquer l'accumulateur aux membres du tableau un par un, et reduce
utiliser la dernière valeur de sortie comme valeur d'entrée suivante. Voici une simple châtaigne pour voir les résultats du calcul de . reduce
const arr = [3, 5, 1, 4, 2]; const a = arr.reduce((t, v) => t + v); // 等同于 const b = arr.reduce((t, v) => t + v, 0);
est essentiellement une fonction d'accumulateur qui utilise un accumulateur défini par l'utilisateur pour personnaliser l'accumulation des membres du tableau et obtenir une valeur générée par l'accumulateur. De plus, reduce
a également un frère cadet reduce
Les fonctions des deux méthodes sont en fait les mêmes, sauf que reduceRight
est exécuté par ordre croissant et reduce
est exécuté par ordre décroissant. reduceRight
对空数组调用reduce()和reduceRight()是不会执行其回调函数的,可认为reduce()对空数组无效
. Afin de montrer le charme de reduce
, je vous propose 25 scénarios pour appliquer l'utilisation avancée de reduce
. Certaines utilisations avancées peuvent devoir être mises en œuvre en combinaison avec d’autres méthodes, ce qui offre davantage de possibilités de diversification. reduce
部分示例代码的写法可能有些骚,看得不习惯可自行整理成自己的习惯写法
reduce
Multiplication cumulativefunction Accumulation(...vals) {
return vals.reduce((t, v) => t + v, 0);
}
function Multiplication(...vals) {
return vals.reduce((t, v) => t * v, 1);
}
Accumulation(1, 2, 3, 4, 5); // 15
Multiplication(1, 2, 3, 4, 5); // 120
const scores = [
{ score: 90, subject: "chinese", weight: 0.5 },
{ score: 95, subject: "math", weight: 0.3 },
{ score: 85, subject: "english", weight: 0.2 }
];
const result = scores.reduce((t, v) => t + v.score * v.weight, 0); // 90.5
function Reverse(arr = []) {
return arr.reduceRight((t, v) => (t.push(v), t), []);
}
Reverse([1, 2, 3, 4, 5]); // [5, 4, 3, 2, 1]
const arr = [0, 1, 2, 3];
// 代替map:[0, 2, 4, 6]
const a = arr.map(v => v * 2);
const b = arr.reduce((t, v) => [...t, v * 2], []);
// 代替filter:[2, 3]
const c = arr.filter(v => v > 1);
const d = arr.reduce((t, v) => v > 1 ? [...t, v] : t, []);
// 代替map和filter:[4, 6]
const e = arr.map(v => v * 2).filter(v => v > 2);
const f = arr.reduce((t, v) => v * 2 > 2 ? [...t, v * 2] : t, []);
const scores = [
{ score: 45, subject: "chinese" },
{ score: 90, subject: "math" },
{ score: 60, subject: "english" }
];
// 代替some:至少一门合格
const isAtLeastOneQualified = scores.reduce((t, v) => t || v.score >= 60, false); // true
// 代替every:全部合格
const isAllQualified = scores.reduce((t, v) => t && v.score >= 60, true); // false
function Chunk(arr = [], size = 1) {
return arr.length ? arr.reduce((t, v) => (t[t.length - 1].length === size ? t.push([v]) : t[t.length - 1].push(v), t), [[]]) : [];
}
const arr = [1, 2, 3, 4, 5];
Chunk(arr, 2); // [[1, 2], [3, 4], [5]]
function Difference(arr = [], oarr = []) {
return arr.reduce((t, v) => (!oarr.includes(v) && t.push(v), t), []);
}
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [2, 3, 6]
Difference(arr1, arr2); // [1, 4, 5]
function Fill(arr = [], val = "", start = 0, end = arr.length) {
if (start < 0 || start >= end || end > arr.length) return arr;
return [
...arr.slice(0, start),
...arr.slice(start, end).reduce((t, v) => (t.push(val || v), t), []),
...arr.slice(end, arr.length)
];
}
const arr = [0, 1, 2, 3, 4, 5, 6];
Fill(arr, "aaa", 2, 5); // [0, 1, "aaa", "aaa", "aaa", 5, 6]
function Flat(arr = []) {
return arr.reduce((t, v) => t.concat(Array.isArray(v) ? Flat(v) : v), [])
}
const arr = [0, 1, [2, 3], [4, 5, [6, 7]], [8, [9, 10, [11, 12]]]];
Flat(arr); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
function Uniq(arr = []) {
return arr.reduce((t, v) => t.includes(v) ? t : [...t, v], []);
}
const arr = [2, 1, 0, 3, 2, 1, 2];
Uniq(arr); // [2, 1, 0, 3]
function Max(arr = []) {
return arr.reduce((t, v) => t > v ? t : v);
}
function Min(arr = []) {
return arr.reduce((t, v) => t < v ? t : v);
}
const arr = [12, 45, 21, 65, 38, 76, 108, 43];
Max(arr); // 108
Min(arr); // 12
function Unzip(arr = []) {
return arr.reduce(
(t, v) => (v.forEach((w, i) => t[i].push(w)), t),
Array.from({ length: Math.max(...arr.map(v => v.length)) }).map(v => [])
);
}
const arr = [["a", 1, true], ["b", 2, false]];
Unzip(arr); // [["a", "b"], [1, 2], [true, false]]
function Count(arr = []) {
return arr.reduce((t, v) => (t[v] = (t[v] || 0) + 1, t), {});
}
const arr = [0, 1, 1, 2, 2, 2];
Count(arr); // { 0: 1, 1: 2, 2: 3 }
此方法是字符统计和单词统计的原理,入参时把字符串处理成数组即可
function Position(arr = [], val) {
return arr.reduce((t, v, i) => (v === val && t.push(i), t), []);
}
const arr = [2, 1, 5, 4, 2, 1, 6, 6, 7];
Position(arr, 2); // [0, 4]
function Group(arr = [], key) {
return key ? arr.reduce((t, v) => (!t[v[key]] && (t[v[key]] = []), t[v[key]].push(v), t), {}) : {};
}
const arr = [
{ area: "GZ", name: "YZW", age: 27 },
{ area: "GZ", name: "TYJ", age: 25 },
{ area: "SZ", name: "AAA", age: 23 },
{ area: "FS", name: "BBB", age: 21 },
{ area: "SZ", name: "CCC", age: 19 }
]; // 以地区area作为分组依据
Group(arr, "area"); // { GZ: Array(2), SZ: Array(2), FS: Array(1) }
function Keyword(arr = [], keys = []) {
return keys.reduce((t, v) => (arr.some(w => w.includes(v)) && t.push(v), t), []);
}
const text = [
"今天天气真好,我想出去钓鱼",
"我一边看电视,一边写作业",
"小明喜欢同桌的小红,又喜欢后桌的小君,真TM花心",
"最近上班喜欢摸鱼的人实在太多了,代码不好好写,在想入非非"
];
const keyword = ["偷懒", "喜欢", "睡觉", "摸鱼", "真好", "一边", "明天"];
Keyword(text, keyword); // ["喜欢", "摸鱼", "真好", "一边"]
function ReverseStr(str = "") {
return str.split("").reduceRight((t, v) => t + v);
}
rrree
const str = "reduce最牛逼";
ReverseStr(str); // "逼牛最ecuder"
function ThousandNum(num = 0) {
const str = (+num).toString().split(".");
const int = nums => nums.split("").reverse().reduceRight((t, v, i) => t + (i % 3 ? v : `${v},`), "").replace(/^,|,$/g, "");
const dec = nums => nums.split("").reduce((t, v, i) => t + ((i + 1) % 3 ? v : `${v},`), "").replace(/^,|,$/g, "");
return str.length > 1 ? `${int(str[0])}.${dec(str[1])}` : int(str[0]);
}
ThousandNum(1234); // "1,234"
ThousandNum(1234.00); // "1,234"
ThousandNum(0.1234); // "0.123,4"
ThousandNum(1234.5678); // "1,234.567,8"
async function AsyncTotal(arr = []) {
return arr.reduce(async(t, v) => {
const at = await t;
const todo = await Todo(v);
at[v] = todo;
return at;
}, Promise.resolve({}));
}
const result = await AsyncTotal(); // 需要在async包围下使用
function Fibonacci(len = 2) {
const arr = [...new Array(len).keys()];
return arr.reduce((t, v, i) => (i > 1 && t.push(t[i - 1] + t[i - 2]), t), [0, 1]);
}
Fibonacci(10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
function ParseUrlSearch() {
return location.search.replace(/(^\?)|(&$)/g, "").split("&").reduce((t, v) => {
const [key, val] = v.split("=");
t[key] = decodeURIComponent(val);
return t;
}, {});
}
// 假设URL为:https://www.baidu.com?age=25&name=TYJ
ParseUrlSearch(); // { age: "25", name: "TYJ" }
function StringifyUrlSearch(search = {}) {
return Object.entries(search).reduce(
(t, v) => `${t}${v[0]}=${encodeURIComponent(v[1])}&`,
Object.keys(search).length ? "?" : ""
).replace(/&$/, "");
}
StringifyUrlSearch({ age: 27, name: "YZW" }); // "?age=27&name=YZW"
function GetKeys(obj = {}, keys = []) {
return Object.keys(obj).reduce((t, v) => (keys.includes(v) && (t[v] = obj[v]), t), {});
}
const target = { a: 1, b: 2, c: 3, d: 4 };
const keyword = ["a", "d"];
GetKeys(target, keyword); // { a: 1, d: 4 }
好用是挺好用的,但是兼容性如何呢?在Caniuse上搜索一番,兼容性绝对的好,可大胆在任何项目上使用。不要吝啬你的想象力,尽情发挥 另外,有些同学可能会问, 以上代码在 我已同时测试过多台机器和多个浏览器,连续做了10次以上操作,发现 最后,送大家一张 原文地址:https://juejin.cn/post/6844904063729926152 作者:JowayYoung 更多编程相关知识,请访问:编程视频!!function Compose(...funs) {
if (funs.length === 0) {
return arg => arg;
}
if (funs.length === 1) {
return funs[0];
}
return funs.reduce((t, v) => (...arg) => t(v(...arg)));
}
兼容和性能
reduce
的compose
技能啦。对于时常做一些累计的功能,reduce
绝对是首选方法。reduce
的性能又如何呢?下面我们通过对for
、forEach
、map
和reduce
四个方法同时做1~100000
的累加操作,看看四个方法各自的执行时间。// 创建一个长度为100000的数组
const list = [...new Array(100000).keys()];
// for
console.time("for");
let result1 = 0;
for (let i = 0; i < list.length; i++) {
result1 += i + 1;
}
console.log(result1);
console.timeEnd("for");
// forEach
console.time("forEach");
let result2 = 0;
list.forEach(v => (result2 += v + 1));
console.log(result2);
console.timeEnd("forEach");
// map
console.time("map");
let result3 = 0;
list.map(v => (result3 += v + 1, v));
console.log(result3);
console.timeEnd("map");
// reduce
console.time("reduce");
const result4 = list.reduce((t, v) => t + v + 1, 0);
console.log(result4);
console.timeEnd("reduce");
累加操作
执行时间
for
6.719970703125ms
forEach
3.696044921875ms
map
3.554931640625ms
reduce
2.806884765625ms
MacBook Pro 2019 15寸 16G内存 512G闪存
的Chrome 79
下执行,不同的机器不同的环境下执行以上代码都有可能存在差异。reduce
总体的平均执行时间还是会比其他三个方法稍微快一点,所以大家还是放心使用啦!本文更多是探讨reduce
的使用技巧,如对reduce
的兼容和性能存在疑问,可自行参考相关资料进行验证。reduce
生成的乘法口诀表:一七得七,二七四十八,三八妇女节,五一劳动节,六一儿童节
。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!