Maison  >  Article  >  interface Web  >  25 utilisations avancées de la réduction des matrices à connaître

25 utilisations avancées de la réduction des matrices à connaître

青灯夜游
青灯夜游avant
2021-07-26 11:37:112138parcourir

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.

25 utilisations avancées de la réduction des matrices à connaître

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 MDNreduce().

    Définition : Exécuter un accumulateur personnalisé sur chaque élément du tableau, résumant ses résultats en une seule valeur de retour
  • Formulaire :
  • array.reduce((t, v, i, a) => {}, initValue)
  • Paramètres
    • callback : fonction de rappel ()必选
    • initValue : initiale value ()可选
  • paramètres de la fonction de rappel
    • total() : valeur renvoyée lorsque l'accumulateur termine le calcul (t)必选
    • value() : élément actuel (v)必选
    • index () : l'index de l'élément actuel (i)可选
    • array() : l'objet tableau auquel appartient l'élément actuel (a)可选
  • process
    • utilise
    • comme valeur initiale du résultat cumulatif, aucun paramètre t commence le parcours avec le premier élément du tableau comme valeur initiale t
    • , utilise l'accumulateur pour traiter
    • , accumule les résultats de mappage de v à v, termine la boucle, revient à tt
    • pour entrer le boucle suivante, et répète l'opération ci-dessus, jusqu'à ce que le dernier élément du tableau
    • termine le parcours et renvoie le
    • t

L'essence est d'appliquer l'accumulateur aux membres du tableau un par un, et reduceutiliser 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);

25 utilisations avancées de la réduction des matrices à connaître

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()对空数组无效

Utilisation avancée

La simple châtaigne ci-dessus ne suffit pas à elle seule à expliquer ce qu'est

. 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 cumulative

function 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

Somme des poids

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

remplacer l'inverse

function Reverse(arr = []) {
    return arr.reduceRight((t, v) => (t.push(v), t), []);
}
Reverse([1, 2, 3, 4, 5]); // [5, 4, 3, 2, 1]

remplacer la carte et le filtre

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, []);

remplacer certains et tout

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

Array split

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

Filtrage du tableau

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]

Remplissage du tableau

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]

Aplatissement du tableau

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]

Déduplication du tableau

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]

Array maximum et minimum valeurs

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

Les membres du tableau sont démontés indépendamment

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

Tableau statistiques du numéro de membre

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 }
此方法是字符统计和单词统计的原理,入参时把字符串处理成数组即可

enregistrement de la position des membres du tableau

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]

groupement des propriétés des membres du tableau

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) }

statistiques des mots clés contenus dans les membres du tableau

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); // ["喜欢", "摸鱼", "真好", "一边"]

string flip ping

function ReverseStr(str = "") {
    return str.split("").reduceRight((t, v) => t + v);
}
rrree

Nombre Mille Différenciation

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]);
}

Accumulation asynchrone

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({}));
}

Séquence de Fibonacci

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]);
}

Désérialisation des paramètres URL

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;
    }, {});
}

Sérialisation des paramètres URL

// 假设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(/&$/, "");
}

Renvoyer la valeur clé spécifiée de l'objet

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), {});
}

Tableau vers objet

const target = { a: 1, b: 2, c: 3, d: 4 };
const keyword = ["a", "d"];
GetKeys(target, keyword); // { a: 1, d: 4 }

Principe de la fonction Redux Compose

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)));
}

兼容和性能

好用是挺好用的,但是兼容性如何呢?在Caniuse上搜索一番,兼容性绝对的好,可大胆在任何项目上使用。不要吝啬你的想象力,尽情发挥reducecompose技能啦。对于时常做一些累计的功能,reduce绝对是首选方法。

25 utilisations avancées de la réduction des matrices à connaître

25 utilisations avancées de la réduction des matrices à connaître

另外,有些同学可能会问,reduce的性能又如何呢?下面我们通过对forforEachmapreduce四个方法同时做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下执行,不同的机器不同的环境下执行以上代码都有可能存在差异。

我已同时测试过多台机器和多个浏览器,连续做了10次以上操作,发现reduce总体的平均执行时间还是会比其他三个方法稍微快一点,所以大家还是放心使用啦!本文更多是探讨reduce的使用技巧,如对reduce的兼容和性能存在疑问,可自行参考相关资料进行验证。

最后,送大家一张reduce生成的乘法口诀表:一七得七,二七四十八,三八妇女节,五一劳动节,六一儿童节

25 utilisations avancées de la réduction des matrices à connaître

25 utilisations avancées de la réduction des matrices à connaître

原文地址:https://juejin.cn/post/6844904063729926152

作者:JowayYoung

更多编程相关知识,请访问:编程视频!!

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer