目次
reduce が何であるかを説明するのに十分ではありません。 reduce
兼容和性能
ホームページ ウェブフロントエンド jsチュートリアル 知っておく価値のある配列リデュースの 25 の高度な使用法

知っておく価値のある配列リデュースの 25 の高度な使用法

Jul 26, 2021 am 11:37 AM
javascript reduce 配列

Reduce は、ES5 の新しい通常の配列メソッドの 1 つであり、強力なメソッドです。この記事では、arrayreduce の 25 の高度な使用法を紹介します。

知っておく価値のある配列リデュースの 25 の高度な使用法

reduce ES5 の新しい通常の配列メソッドの 1 つとして、forEachfilter、およびmap は、実際の使用では無視されているようで、私の周りでもほとんど使用していないことがわかり、このような強力なメソッドは徐々に埋もれています。

reduce を頻繁に使用する場合、このような便利なツールを見逃すはずがありません。私はまだそれを埃から取り出し、きれいに拭き、その高度な使い方を皆さんに提供する必要があります。このような有用な方法が世間に埋もれてしまってはなりません。

以下は、reduce の構文の簡単な説明です。詳細については、MDNreduce() の関連手順を参照してください。 。

  • 定義: 配列内の各要素に対してカスタム アキュムレータを実行し、その結果を 1 つの戻り値に要約します。
  • 形式: array.reduce(( t, v, i, a) => {}, initValue)
  • パラメータ
    • callback: コールバック関数 (required)
    • initValue: 初期値 (optional)
  • コールバック関数のパラメータ
    • total(t): アキュムレータが計算を完了したときの戻り値 (Required)
    • value(v): 現在の要素 (Required)
    • index(i): 現在の要素のインデックス ( Optional) )
    • array(a): 現在の要素が属する配列オブジェクト (Optional)
  • 処理
    • 累積結果の初期値としてtを使用します。tが設定されていない場合、配列の最初の要素が初期値になります。
    • トラバースを開始し、アキュムレータを使用して v を処理し、v のマッピング結果を t に蓄積し、ループを終了して # を返します。 ##t # 次のループに入り、配列
    • の最後の要素でトラバーサルが終了し、最後の
    • t
    • ## が返されるまで上記の操作を繰り返します。
  • reduce
本質は、

最後の出力値を次の入力値として取得し、アキュムレータを配列メンバーに 1 つずつ適用することです。 。 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);
ログイン後にコピー

reduce知っておく価値のある配列リデュースの 25 の高度な使用法 は本質的にアキュムレータ関数であり、ユーザー定義のアキュムレータを使用して配列メンバーの累積をカスタマイズし、次によって生成される値を取得します。アキュムレータ。さらに、

reduce

には弟の reduceRight もあります。この 2 つのメソッドの機能は、reduce が昇順で実行されることを除いて、実際には同じです。 ##reduceRight 降順に実行されます。

对空数组调用reduce()和reduceRight()是不会执行其回调函数的,可认为reduce()对空数组无效
ログイン後にコピー
高度な使用法

上記の単純な説明だけでは、

reduce が何であるかを説明するのに十分ではありません。 reduce

の魅力を示すために、

reduce の高度な使用法を適用する 25 のシナリオを提供します。一部の高度な使用方法は、他のメソッドと組み合わせて実装する必要がある場合があります。これにより、reduce の多様化の可能性が高まります。

部分示例代码的写法可能有些骚,看得不习惯可自行整理成自己的习惯写法
ログイン後にコピー
累積乗算
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
ログイン後にコピー

重みの合計

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), [[]]) : [];
}
ログイン後にコピー
rree

配列フィルタリング

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), [])
}
ログイン後にコピー

# #Array重複排除

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);
}
ログイン後にコピー
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包围下使用
ログイン後にコピー

#URLパラメータのデシリアライゼーション

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]
ログイン後にコピー

URL パラメータのシリアル化

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), {});
}
ログイン後にコピー

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 の高度な使用法

知っておく価値のある配列リデュースの 25 の高度な使用法

另外,有些同学可能会问,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 の高度な使用法

知っておく価値のある配列リデュースの 25 の高度な使用法

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

作者:JowayYoung

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

以上が知っておく価値のある配列リデュースの 25 の高度な使用法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

foreach ループを使用して PHP 配列から重複要素を削除するにはどうすればよいですか? foreach ループを使用して PHP 配列から重複要素を削除するにはどうすればよいですか? Apr 27, 2024 am 11:33 AM

foreach ループを使用して PHP 配列から重複要素を削除する方法は次のとおりです。配列を走査し、要素がすでに存在し、現在の位置が最初に出現しない場合は、要素を削除します。たとえば、データベース クエリの結果に重複レコードがある場合、このメソッドを使用してそれらを削除し、重複レコードのない結果を取得できます。

PHP 配列キー値の反転: さまざまな方法のパフォーマンス比較分析 PHP 配列キー値の反転: さまざまな方法のパフォーマンス比較分析 May 03, 2024 pm 09:03 PM

PHP の配列キー値の反転メソッドのパフォーマンスを比較すると、array_flip() 関数は、大規模な配列 (100 万要素以上) では for ループよりもパフォーマンスが良く、所要時間が短いことがわかります。キー値を手動で反転する for ループ方式は、比較的長い時間がかかります。

PHP 配列ディープ コピーの技術: さまざまな方法を使用して完璧なコピーを実現する PHP 配列ディープ コピーの技術: さまざまな方法を使用して完璧なコピーを実現する May 01, 2024 pm 12:30 PM

PHP で配列をディープ コピーする方法には、json_decode と json_encode を使用した JSON エンコードとデコードが含まれます。 array_map と clone を使用して、キーと値のディープ コピーを作成します。シリアル化と逆シリアル化には、serialize と unserialize を使用します。

PHP 配列の多次元ソートの実践: 単純なシナリオから複雑なシナリオまで PHP 配列の多次元ソートの実践: 単純なシナリオから複雑なシナリオまで Apr 29, 2024 pm 09:12 PM

多次元配列のソートは、単一列のソートとネストされたソートに分類できます。単一列のソートでは、array_multisort() 関数を使用して列ごとにソートできますが、ネストされたソートでは、配列を走査してソートするための再帰関数が必要です。具体的な例としては、製品名による並べ替えや、売上数量や価格による化合物の並べ替えなどがあります。

PHP 配列のディープ コピーのベスト プラクティス: 効率的な方法を発見する PHP 配列のディープ コピーのベスト プラクティス: 効率的な方法を発見する Apr 30, 2024 pm 03:42 PM

PHP で配列のディープ コピーを実行するためのベスト プラクティスは、 json_decode(json_encode($arr)) を使用して配列を JSON 文字列に変換し、それから配列に戻すことです。 unserialize(serialize($arr)) を使用して配列を文字列にシリアル化し、それを新しい配列に逆シリアル化します。 RecursiveIteratorIterator を使用して、多次元配列を再帰的に走査します。

データソートにおけるPHP配列グループ化機能の応用 データソートにおけるPHP配列グループ化機能の応用 May 04, 2024 pm 01:03 PM

PHP の array_group_by 関数は、キーまたはクロージャ関数に基づいて配列内の要素をグループ化し、キーがグループ名、値がグループに属する要素の配列である連想配列を返すことができます。

重複要素の検索における PHP 配列グループ化関数の役割 重複要素の検索における PHP 配列グループ化関数の役割 May 05, 2024 am 09:21 AM

PHP の array_group() 関数を使用すると、指定したキーで配列をグループ化し、重複する要素を見つけることができます。この関数は次の手順で動作します。 key_callback を使用してグループ化キーを指定します。必要に応じて、value_callback を使用してグループ化値を決定します。グループ化された要素をカウントし、重複を特定します。したがって、array_group() 関数は、重複する要素を見つけて処理するのに非常に役立ちます。

PHP 配列のマージおよび重複排除アルゴリズム: 並列ソリューション PHP 配列のマージおよび重複排除アルゴリズム: 並列ソリューション Apr 18, 2024 pm 02:30 PM

PHP 配列のマージおよび重複排除アルゴリズムは、元の配列を小さなブロックに分割して並列処理する並列ソリューションを提供し、メイン プロセスは重複排除するブロックの結果をマージします。アルゴリズムのステップ: 元の配列を均等に割り当てられた小さなブロックに分割します。重複排除のために各ブロックを並行して処理します。ブロックの結果をマージし、再度重複排除します。

See all articles