Heim  >  Artikel  >  Web-Frontend  >  25 erweiterte Einsatzmöglichkeiten von Arrays reduzieren Wissenswertes

25 erweiterte Einsatzmöglichkeiten von Arrays reduzieren Wissenswertes

青灯夜游
青灯夜游nach vorne
2021-07-26 11:37:112132Durchsuche

Reduce ist als eine der neuen regulären Array-Methoden in ES5 eine leistungsstarke Methode. In diesem Artikel werden Ihnen 25 erweiterte Anwendungen der Array-Reduzierung vorgestellt.

25 erweiterte Einsatzmöglichkeiten von Arrays reduzieren Wissenswertes

reduce ist eine der neuen regulären Array-Methoden in ES5, vergleiche forEach, filter und map, es scheint in der tatsächlichen Verwendung etwas ignoriert zu werden, und es wurde festgestellt, dass die Menschen um mich herum es selten verwenden, was dazu führte, dass eine so leistungsstarke Methode nach und nach begraben wurde. reduce作为ES5新增的常规数组方法之一,对比forEachfiltermap,在实际使用上好像有些被忽略,发现身边的人极少使用它,导致这个如此强大的方法被逐渐埋没。

如果经常使用reduce,怎么可能放过如此好用的它呢!我还是得把他从尘土中取出来擦干净,奉上它的高级用法给大家。一个如此好用的方法不应该被大众埋没。

下面对reduce的语法进行简单说明,详情可查看MDNreduce()的相关说明。

  • 定义:对数组中的每个元素执行一个自定义的累计器,将其结果汇总为单个返回值
  • 形式:array.reduce((t, v, i, a) => {}, initValue)
  • 参数
    • callback:回调函数(必选)
    • initValue:初始值(可选)
  • 回调函数的参数
    • total(t):累计器完成计算的返回值(必选)
    • value(v):当前元素(必选)
    • index(i):当前元素的索引(可选)
    • array(a):当前元素所属的数组对象(可选)
  • 过程
    • t作为累计结果的初始值,不设置t则以数组第一个元素为初始值
    • 开始遍历,使用累计器处理v,将v的映射结果累计到t上,结束此次循环,返回t
    • 进入下一次循环,重复上述操作,直至数组最后一个元素
    • 结束遍历,返回最终的t

reduce的精华所在是将累计器逐个作用于数组成员上,把上一次输出的值作为下一次输入的值。下面举个简单的栗子,看看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 erweiterte Einsatzmöglichkeiten von Arrays reduzieren Wissenswertes

reduce实质上是一个累计器函数,通过用户自定义的累计器对数组成员进行自定义累计,得出一个由累计器生成的值。另外reduce还有一个胞弟reduceRight,两个方法的功能其实是一样的,只不过reduce是升序执行,reduceRight是降序执行。

对空数组调用reduce()和reduceRight()是不会执行其回调函数的,可认为reduce()对空数组无效

高级用法

单凭以上一个简单栗子不足以说明reduce是个什么。为了展示reduce的魅力,我为大家提供25种场景来应用reduce的高级用法。有部分高级用法可能需要结合其他方法来实现,这样为reduce

Wenn Sie reduce häufig verwenden, wie könnten Sie dann ein so nützliches Tool verpassen? Ich muss es noch aus dem Staub nehmen, es sauber wischen und Ihnen seine erweiterten Verwendungsmöglichkeiten anbieten. Eine solch nützliche Methode sollte nicht von der Öffentlichkeit vertuscht werden.

Die Syntax von reduce wird unten kurz erläutert. Einzelheiten finden Sie unter 部分示例代码的写法可能有些骚,看得不习惯可自行整理成自己的习惯写法

25 erweiterte Einsatzmöglichkeiten von Arrays reduzieren Wissenswertes

reduce ist im Wesentlichen eine Akkumulatorfunktion, die einen benutzerdefinierten Akkumulator verwendet, um Array-Mitglieder zu akkumulieren, um einen vom Akkumulator generierten Wert zu erhalten. Darüber hinaus hat reduce einen jüngeren Bruder reduceRight. Die Funktionen der beiden Methoden sind eigentlich gleich, außer dass reduce in aufsteigender Reihenfolge ausgeführt wird , reduceRight wird in absteigender Reihenfolge ausgeführt.

function Accumulation(...vals) {
    return vals.reduce((t, v) => t + v, 0);
}

function Multiplication(...vals) {
    return vals.reduce((t, v) => t * v, 1);
}

Erweiterte Verwendung

Die obige einfache Kastanie allein reicht nicht aus, um zu erklären, was reduce ist. Um den Charme von reduce zu demonstrieren, stelle ich Ihnen 25 Szenarien zur Verfügung, in denen Sie die erweiterte Verwendung von reduce anwenden können. Möglicherweise muss eine erweiterte Verwendung in Kombination mit anderen Methoden implementiert werden, was mehr Möglichkeiten für die Diversifizierung von reduce bietet.

Accumulation(1, 2, 3, 4, 5); // 15
Multiplication(1, 2, 3, 4, 5); // 120

Kumulative Multiplikation

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

Summe der Gewichte

Reverse([1, 2, 3, 4, 5]); // [5, 4, 3, 2, 1]

Umkehrung ersetzen

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

Karte und Filter ersetzen

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

Ersetzen Sie einige und alle Array-Filterung Maximal- und Minimalwerte des Arrays

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

Array-Mitglieder werden unabhängig voneinander zerlegt

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

Statistiken über die Anzahl der Array-Mitglieder

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]

Array-Mitgliedsstandortdatensatz

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

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

In Array-Mitgliedern enthaltene Schlüsselwortstatistiken

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

String-Flip

function Count(arr = []) {
    return arr.reduce((t, v) => (t[v] = (t[v] || 0) + 1, t), {});
}
rrree

Number Thousand Differentiation

const arr = [0, 1, 1, 2, 2, 2];
Count(arr); // { 0: 1, 1: 2, 2: 3 }
此方法是字符统计和单词统计的原理,入参时把字符串处理成数组即可

Asynchrone Akkumulation

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]

Fibonacci-Sequenz

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

URL-Parameter-Deserialisierung

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

URL-Parameter-Serialisierung

function ReverseStr(str = "") {
    return str.split("").reduceRight((t, v) => t + v);
}
const str = "reduce最牛逼";
ReverseStr(str); // "逼牛最ecuder"

Gibt den angegebenen Schlüsselwert des Objekts zurück

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"

Array Einspruch erheben

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

🎜Redux Compose-Funktionsprinzip🎜🎜
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 erweiterte Einsatzmöglichkeiten von Arrays reduzieren Wissenswertes

25 erweiterte Einsatzmöglichkeiten von Arrays reduzieren Wissenswertes

另外,有些同学可能会问,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 erweiterte Einsatzmöglichkeiten von Arrays reduzieren Wissenswertes

25 erweiterte Einsatzmöglichkeiten von Arrays reduzieren Wissenswertes

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

作者:JowayYoung

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

Das obige ist der detaillierte Inhalt von25 erweiterte Einsatzmöglichkeiten von Arrays reduzieren Wissenswertes. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen