<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用 JavaScript 進行數(shù)據(jù)分組最優(yōu)雅的方式

          共 2758字,需瀏覽 6分鐘

           ·

          2021-12-29 01:43

          今天我們一起來看一個數(shù)據(jù)分組的小技巧。

          對數(shù)據(jù)進行分組,是我們在開發(fā)中經(jīng)常會遇到的需求,使用 JavaScript 進行數(shù)據(jù)分組的方式也有很多種,但是由于沒有原生方法的支持,我們自己實現(xiàn)的數(shù)據(jù)分組函數(shù)通常都比較冗長而且難以理解。

          不過,告訴大家一個好消息,一個專門用來做數(shù)據(jù)分組的提案 Array.prototype.groupBy 已經(jīng)到達 Stage 3 啦!

          在看這個提案,之前,我們先來回顧下我們以前在 JavaScript 里是怎么分組的。

          以前的方式

          假設(shè)我們有下面一組數(shù)據(jù):

          const?items?=?[
          ??{
          ????type:?'clothes',
          ????value:?'??',
          ??},
          ??{
          ????type:?'clothes',
          ????value:?'??',
          ??},
          ??{
          ????type:?'clothes',
          ????value:?'??',
          ??},
          ??{
          ????type:?'animal',
          ????value:?'??',
          ??},
          ??{
          ????type:?'animal',
          ????value:?'??',
          ??},
          ??{
          ????type:?'animal',
          ????value:?'??',
          ??},
          ];

          我們希望按照 type 分組成下面的格式:

          const?items?=?{
          ??clothes:?[
          ????{
          ??????type:?'clothes',
          ??????value:?'??',
          ????},
          ????{
          ??????type:?'clothes',
          ??????value:?'??',
          ????},
          ????{
          ??????type:?'clothes',
          ??????value:?'??',
          ????},
          ??],
          ??animal:?[
          ????{
          ??????type:?'animal',
          ??????value:?'??',
          ????},
          ????{
          ??????type:?'animal',
          ??????value:?'??',
          ????},
          ????{
          ??????type:?'animal',
          ??????value:?'??',
          ????},
          ??],
          };

          我們可能會用到下面的寫法:

          for 循環(huán)

          最直接而且容易理解的方法,就是代碼有點多。

          const?groupedBy?=?{};

          for?(const?item?of?items)?{
          ??if?(groupedBy[item.type])?{
          ????groupedBy[item.type].push(item);
          ??}?else?{
          ????groupedBy[item.type]?=?[item];
          ??}
          }

          reduce

          使用 Array.protoype.reduce 雖然語法看起來簡單,但是太難讀了。

          items.reduce(
          ??(acc,?item)?=>?({
          ????...acc,
          ????[item.type]:?[...(acc[item.type]????[]),?item],
          ??}),
          ??{},
          );

          我們稍微改造的容易理解一點,語法就跟上面的 for 循環(huán)差不多了:

          items.reduce((acc,?item)?=>?{
          ??if?(acc[item.type])?{
          ????acc[item.type].push(item);
          ??}?else?{
          ????acc[item.type]?=?[item];
          ??}

          ??return?acc;
          },?{});

          filter

          使用 Array.prototype.filter,代碼看起來很容易閱讀,但是性能很差,你需要對數(shù)組進行多次過濾,而且如果 type 屬性值比較多的情況下,還需要做更多的 filter 操作。

          const?groupedBy?=?{
          ??fruit:?items.filter((item)?=>?item.type?===?'clothes'),
          ??vegetable:?items.filter((item)?=>?item.type?===?'animal'),
          };

          其他

          如果你既不想用 reduce,還想用到函數(shù)式寫法,你可能會寫出下面的代碼:

          Object.fromEntries(
          ??Array.from(new?Set(items.map(({?type?})?=>?type))).map((type)?=>?[
          ????type,
          ????items.filter((item)?=>?item.type?===?type),
          ??]),
          );

          是不是很讓人崩潰 ??~

          Array.prototype.groupBy

          好了,如果使用 Array.prototype.groupBy,你只需要下面這一行代碼:

          items.groupBy(({?type?})?=>?type);

          groupBy 的回調(diào)中一共有三個參數(shù):

          • 參數(shù)1:數(shù)組遍歷到的當前對象
          • 參數(shù)2:index 索引
          • 參數(shù)3:原數(shù)組
          const?array?=?[1,?2,?3,?4,?5];

          //?groupBy?groups?items?by?arbitrary?key.
          //?In?this?case,?we're?grouping?by?even/odd?keys
          array.groupBy((num,?index,?array)?=>?{
          ??return?num?%?2?===?0???'even':?'odd';
          });

          另外,你還可以用 groupByToMap,將數(shù)據(jù)分組為一個 Map 對象。

          //?groupByToMap?returns?items?in?a?Map,?and?is?useful?for?grouping?using
          //?an?object?key.
          const?odd??=?{?odd:?true?};
          const?even?=?{?even:?true?};
          array.groupByToMap((num,?index,?array)?=>?{
          ??return?num?%?2?===?0???even:?odd;
          });

          //?=>??Map?{?{odd:?true}:?[1,?3,?5],?{even:?true}:?[2,?4]?}

          參考:

          • https://github.com/tc39/proposal-array-grouping
          • https://www.charpeni.com/blog/array-prototype-group-by-to-the-rescue

          瀏覽 70
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产小穴 | 国产成人无码综合亚洲日韩不卡 | 在线观看免费黄色 | 国产色婷婷视频在线观看 | 亚洲va欧美ⅴa在线 |