序文Reduce は ES5 で追加された新しい従来の配列メソッドの 1 つです。forEach、filter、map と比較すると、実際の使用ではやや軽視されているようです。私の周りの人々もあまり使用していないことがわかり、このような強力なメソッドが徐々に埋もれていくことにつながっています。 頻繁にreduceを使用するのであれば、このような便利なものを見逃すわけにはいきません。まだ埃の中から取り出して、きれいに拭いて、その高度な使い方をみんなに紹介しなければなりません。このような有用な方法は、世間に埋もれるべきではない。 以下は、reduce の構文の簡単な説明です。詳細については、MDN の Reduce() の関連する説明を参照してください。
Reduce の本質は、配列メンバーに 1 つずつ累積器を適用し、前の出力の値を次の入力の値として使用することです。簡単な例を使って、reduce の計算結果を見てみましょう。 定数arr = [3, 5, 1, 4, 2]; 定数 a = arr.reduce((t, v) => t + v); // 次と同等 const b = arr.reduce((t, v) => t + v, 0); コードがよくわからなくても大丈夫です。reduce 関数の GIF を投稿すれば理解できるはずです。 Reduce は、基本的に、ユーザー定義のアキュムレータを介して配列メンバーに対してカスタム累積を実行し、アキュムレータによって生成された値を取得するアキュムレータ関数です。さらに、reduce には弟分の ReduceRight があります。2 つのメソッドの機能は実際には同じですが、reduce は昇順で実行され、reduceRight は降順で実行される点が異なります。
高度な使用法上記の簡単な例だけでは、reduce が何であるかを説明するには不十分です。 Reduce の威力を示すために、Reduce の高度な使用法を適用するための 25 のシナリオを紹介します。いくつかの高度な使用法は、他の方法と組み合わせて実現する必要がある場合があり、これにより、reduce の多様化の可能性が広がります。 一部のサンプルコードの書き方は少々雑なところがあるかもしれません。慣れていない方は自分の癖に合わせて書き直してください。 蓄積して増やす 関数 Accumulation(...vals) { vals.reduce((t, v) => t + v, 0) を返します。 } 関数乗算(...vals) { vals.reduce((t, v) => t * v, 1); を返します。 } 累積(1, 2, 3, 4, 5); // 15 乗算(1, 2, 3, 4, 5); // 120 加重合計 定数スコア = [ { スコア: 90、件名: "中国語"、重み: 0.5 }、 { スコア: 95、科目: "数学"、重み: 0.3 }、 { スコア: 85、件名: "英語"、重み: 0.2 } ]; const result = scores.reduce((t, v) => t + v.score * v.weight, 0); // 90.5 逆に 関数Reverse(arr = []) { arr.reduceRight((t, v) => (t.push(v), t), []); を返します。 } 逆順([1, 2, 3, 4, 5]); // [5, 4, 3, 2, 1] マップとフィルターを置き換える 定数arr = [0, 1, 2, 3]; // マップを置き換える: [0, 2, 4, 6] 定数a = arr.map(v => v * 2); 定数 b = arr.reduce((t, v) => [...t, v * 2], []); // フィルターを置換: [2, 3] 定数 c = arr.filter(v => v > 1); 定数 d = arr.reduce((t, v) => v > 1 ? [...t, v] : t, []); // マップとフィルターを置き換えます: [4, 6] 定数 e = arr.map(v => v * 2).filter(v => v > 2); 定数 f = arr.reduce((t, v) => v * 2 > 2 ? [...t, v * 2] : t, []); 一部と全部を置き換える 定数スコア = [ { スコア: 45、件名: "中国語" }, { スコア: 90、科目: "数学" }, { スコア: 60、件名: "英語" } ]; // いくつかを置き換えます: 少なくとも 1 つの修飾子 const isAtLeastOneQualified = scores.reduce((t, v) => t || v.score >= 60, false); // true // すべて置換: すべて修飾子付き const isAllQualified = scores.reduce((t, v) => t && v.score >= 60, true); // false 配列の分割 関数Chunk(arr = [], サイズ = 1) { arr.length を返します。arr.reduce((t, v) => (t[t.length - 1].length === size ? t.push([v]) : t[t.length - 1].push(v), t), [[]]) : []; } 定数arr = [1, 2, 3, 4, 5]; チャンク(arr, 2); // [[1, 2], [3, 4], [5]] 配列フィルタリング 関数 Difference(arr = [], oarr = []) { arr.reduce((t, v) => (!oarr.includes(v) && t.push(v), t), []); を返します。 } 定数arr1 = [1, 2, 3, 4, 5]; 定数arr2 = [2, 3, 6] 差(arr1, arr2); // [1, 4, 5] 配列の充填 関数Fill(arr = [], val = "", start = 0, end = arr.length) { start < 0 || start >= end || end > arr.length の場合、arr を返します。 戻る [ ...arr.slice(0, 開始), ...arr.slice(start, end).reduce((t, v) => (t.push(val || v), t), []), ...arr.slice(終了、arr.length) ]; } 定数arr = [0, 1, 2, 3, 4, 5, 6]; Fill(arr, "aaa", 2, 5); // [0, 1, "aaa", "aaa", "aaa", 5, 6] 配列の平坦化 関数 Flat(arr = []) { arr.reduce((t, v) => t.concat(Array.isArray(v) ? Flat(v) : v), []) を返します。 } 定数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] アレイ重複排除 関数Uniq(arr = []) { arr.reduce((t, v) => t.includes(v) ? t : [...t, v], []); を返します。 } 定数arr = [2, 1, 0, 3, 2, 1, 2]; ユニーク(arr); // [2, 1, 0, 3] 配列の最大値と最小値 関数Max(arr = []) { arr.reduce((t, v) => t > v ? t : v); を返します。 } 関数 Min(arr = []) { arr.reduce((t, v) => t < v ? t : v); を返します。 } 定数arr = [12, 45, 21, 65, 38, 76, 108, 43]; 最大(arr); // 108 最小(arr); // 12 配列メンバーは独立して分解される 関数Unzip(arr = []) { 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 => []) ); } 定数 arr = [["a", 1, true], ["b", 2, false]]; Unzip(arr); // [["a", "b"], [1, 2], [true, false]] 配列メンバー数 関数Count(arr = []) { arr.reduce((t, v) => (t[v] = (t[v] || 0) + 1, t), {}); を返します。 } 定数arr = [0, 1, 1, 2, 2, 2]; Count(arr); // { 0: 1, 1: 2, 2: 3 } この方法は、文字統計と単語統計の原理に基づいています。パラメータを入力すると、文字列を配列に処理するだけです。 配列メンバー位置レコード 関数 Position(arr = [], val) { arr.reduce((t, v, i) => (v === val && t.push(i), t), []); を返します。 } 定数arr = [2, 1, 5, 4, 2, 1, 6, 6, 7]; 位置(arr, 2); // [0, 4] 配列メンバー属性のグループ化 関数グループ(arr = [], キー) { キーを返します? arr.reduce((t, v) => (!t[v[key]] && (t[v[key]] = []), t[v[key]].push(v), t), {}) : {}; } 定数arr = [ { 地域: "GZ", 名前: "YZW", 年齢: 27 }, { 地域: "GZ", 名前: "TYJ", 年齢: 25 }, { エリア: "SZ", 名前: "AAA", 年齢: 23 }, { エリア: "FS", 名前: "BBB", 年齢: 21 }, { エリア: "SZ", 名前: "CCC", 年齢: 19 } ]; // グループ化の基準として面積を使用する Group(arr, "area"); // { GZ: Array(2), SZ: Array(2), FS: Array(1) } 配列メンバーのキーワード統計 関数キーワード(arr = [], keys = []) { 戻り値 keys.reduce((t, v) => (arr.some(w => w.includes(v)) && t.push(v), t), []); } 定数テキスト = [ 「今日はいい天気だから釣りに行きたい」 「宿題をしながらテレビを見ます」 「シャオミンは、隣に座っているシャオホンと、隣に座っているシャオジュンが好きです。彼はとても気まぐれです」 「最近、仕事をサボりたがる人が多すぎる。ちゃんとコードを書かずに空想にふけっている。」 ]; const keyword = ["lazy", "like", "sleep", "fishing", "great", "while", "tomorrow"]; Keyword(text, keyword); // ["like", "slacking off", "really nice", "while"] 文字列の反転 関数ReverseStr(str = "") { str.split("").reduceRight((t, v) => t + v); を返します。 } const str = "reduce が最善です"; ReverseStr(str); // "最も強力なエクーダー" デジタルミレニアル世代 関数 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, ""); 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" 非同期蓄積 非同期関数 AsyncTotal(arr = []) { 戻り値 arr.reduce(async(t, v) => { 定数 at = t を待機します。 todo を待機します。 at[v] = する; 戻る; }, Promise.resolve({})); } const result = await AsyncTotal(); // 非同期サラウンドで使用する必要があります フィボナッチ数列 関数フィボナッチ(len = 2) { const arr = [...新しい配列(len).keys()]; arr.reduce((t, v, i) => (i > 1 && t.push(t[i - 1] + t[i - 2]), t), [0, 1]); を返します。 } フィボナッチ(10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] URLパラメータのデシリアライズ 関数 ParseUrlSearch() { location.search.replace(/(^\?)|(&$)/g, "").split("&").reduce((t, v) => { を返します。 const [キー、値] = v.split("="); t[キー] = decodeURIComponent(val); t を返します。 }, {}); } // URL が https://www.baidu.com?age=25&name=TYJ であると仮定します。 ParseUrlSearch(); // { 年齢: "25", 名前: "TYJ" } URLパラメータのシリアル化 関数 StringifyUrlSearch(検索 = {}) { 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" オブジェクト内の指定されたキーの値を返します 関数 GetKeys(obj = {}, keys = []) { Object.keys(obj).reduce((t, v) => (keys.includes(v) && (t[v] = obj[v]), t), {}); を返します。 } 定数ターゲット = { a: 1、 b: 2、 c: 3、 d: 4 }; const キーワード = ["a", "d"]; GetKeys(ターゲット、キーワード); // { a: 1, d: 4 } 配列からオブジェクトへ 定数人 = [ { 地域: "GZ", 名前: "YZW", 年齢: 27 }, { エリア: "SZ", 名前: "TYJ", 年齢: 25 } ]; const map = people.reduce((t, v) => { const { 名前、... 残り } = v; t[名前] = 残り; t を返します。 }, {}); // { YZW: {…}, TYJ: {…} } Redux Compose関数の原則 関数Compose(...関数) { (関数の長さが0の場合){ 引数 => 引数を返します。 } 関数の長さが1の場合 funs[0]を返します。 } funs.reduce((t, v) => (...arg) => t(v(...arg))); を返します。 } 互換性とパフォーマンス使いやすいですが、互換性はどうでしょうか? Caniuse で検索すると、互換性が非常に高く、どのプロジェクトでも大胆に使用できます。想像力を惜しまず、文章作成スキルをフルに発揮してください。頻繁に何らかの累積を実行する関数の場合、reduce が間違いなく推奨される方法です。 さらに、reduce のパフォーマンスはどうなのかと尋ねる学生もいるかもしれません。次に、for、forEach、map、reduce の 4 つのメソッドに対して 1 から 100,000 までの累積演算を同時に実行し、4 つのメソッドそれぞれの実行時間を確認します。 // 長さ 100000 の配列を作成します。const list = [...new Array(100000).keys()]; // のために console.time("に対して"); 結果1 = 0 とします。 (i = 0 とします; i < list.length; i++) { 結果1 += i + 1; } コンソールログ(結果1); console.timeEnd("for"); // 各 コンソールで時間を設定します。 結果2 = 0 とします。 リスト.forEach(v => (result2 += v + 1)); コンソールログ(結果2); コンソールのtimeEnd("forEach"); // マップ console.time("マップ"); 結果3 = 0 とします。 list.map(v => (result3 += v + 1, v)); コンソールログ(結果3); console.timeEnd("マップ"); // 減らす console.time("短縮"); const result4 = list.reduce((t, v) => t + v + 1, 0); コンソールログ(結果4); console.timeEnd("減らす");
上記のコードは、16G メモリと 512G フラッシュ メモリを搭載した MacBook Pro 2019 15 インチの Chrome 79 で実行されています。マシンや環境によって、上記のコードの実行結果が異なる場合があります。 複数のマシンと複数のブラウザを同時にテストし、10 回以上連続して操作を実行しました。reduce の全体的な平均実行時間は、他の 3 つの方法よりもわずかに速いことがわかりましたので、安心して使用できます。この記事では主にreduceの使用テクニックについて説明しています。reduceの互換性やパフォーマンスについて疑問がある場合は、関連資料を参照して検証することができます。 最後に、reduce によって生成された掛け算の表を示します。1 を 7 倍すると 7、2 を 7 倍すると 48、3 月 8 日は国際女性デー、5 月 1 日は労働者の日、6 月 1 日は子供の日です。 要約するこれで、知っておくべき JS 配列の削減の高度な使用法 25 個に関するこの記事は終了です。JS 配列の削減の高度な使用法に関する詳細なコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: MySQLのユーザーアカウント管理と権限管理の詳細な説明
>>: Tomcat および Web アプリケーションの Docker デプロイメントの実装
恥ずかしながら、このようなよく使われるチェックボックスのスタイルを変更するために、Baidu で長い...
<br />この Web ページ制作スキル チュートリアルは、Web サイトのアイコンを...
Docker をインストールした後、会社が構築したプライベート サーバー Harbor からプルしよ...
目次1. 実施プロセス2. オブザーバーを表示する3. ウォッチャーを実装する4. コンパイルを実装...
MySQL のバージョンは、Enterprise Edition と Community Editi...
この記事では主に、CSS3 フレックスレイアウトを使用して要素を均等に配置する方法を紹介します。自分...
Web ページのパフォーマンスを向上させるにはどうすればよいでしょうか?ほとんどの開発者は、Java...
目次Vuex環境を構築する要約するVuex環境を構築するsrcディレクトリにフォルダstoreを作成...
Vue では、一般的にフロントエンドとバックエンドを分離したプロジェクトがあり、データ操作を実装する...
CSS3 は、要素の 2D 平面変換と視覚的な 3D 空間変換を実装します。2D 変換はより頻繁に使...
コードを書くとき、2 つのファイル間の違い、または同じファイルの異なるバージョン間の違いを知る必要が...
1 問題の説明この記事では、確立された複合インデックスをソートし、レコード内の非インデックス フィー...
リレーショナル データベースでは、悲観的ロックと楽観的ロックがリソース同時実行シナリオのソリューショ...
目次1. すべて選択2. 商品の数量を増やすか減らす3. 商品の小計を変更する4. 合計と合計額を計...
MySQL データをエクスポートする目的は、データベースのバックアップ、テーブル構造のエクスポート、...