簡體   English   中英

文章數組基於Javascript reduce主題拆分為子數組

[英]Array of Articles split into subarrays based on topic with Javascript reduce

我正在嘗試根據第一個鍵值對將一組文章拆分為子數組,並且它是順序。

我已經查看了許多Stack Overflow帖子,我認為這是最適合我想要完成的事情:

基於屬性將對象數組分成單獨的數組

我知道有關減少的問題經常被問到,但是我被絆倒了,這是我找不到的答案:

有什么不同:我不想將數組過濾成兩個獨立的類別(即“標記”和“視頻”),而是讓第一個數組成為“視頻”項目的所有“標記”項目,制作包含所有“視頻”項目的數組,直到下一個“標記”項目,創建所有“標記”項目的新數組,直到下一個“視頻”項目等。

這是一個REPL再現我正在嘗試做的事: REPL再現問題

數據如下所示:

export default [{
  "type": "markup",
  "element": "p",
  "html": "blah"
}, {
  "type": "markup",
  "element": "p",
  "html": "blah"
}, {
  "type": "markup",
  "element": "p",
  "html": "blah"
}, {
  "type": "embeddedVideo",
  "element": "p",
  "html": "embeddedWidget"
}, {
  "type": "markup",
  "element": "p",
  "html": "blah"
},
{
  "type": "markup",
  "element": "p",
  "html": "blah"
},
]

使用JavaScript reduce后我希望它看起來像是:

[
  [
    {type: 'markup', element: 'p', html: 'blah' /*...*/ },
    {type: 'markup', element: 'p', html: 'blah' /*...*/ },
    {type: 'markup', element: 'p', html: 'blah' /*...*/ }
  ],
  [
    {type: 'embeddedVideo', /*...*/ }
  ],
  [
    {type: 'markup', element: 'p', html: 'blah' /*...*/ },
    {type: 'markup', element: 'p', html: 'blah' /*...*/ },
    {type: 'markup', element: 'p', html: 'blah' /*...*/ }
  ]
]

到目前為止我所擁有的是:

import articleBody from './articleBody.js';


 function groupBy(arr, property) {
  return arr.reduce((prop, x) => {
    if (!prop[x[property]]) { prop[x[property]] = []; }
    prop[x[property]].push(x);
    return prop;
  }, {});
}

let outputSample = groupBy(articleBody, "type");

console.log(outputSample)

這段代碼只創建了2個數組(一個帶有標記,一個帶有視頻),它沒有記住原始數據的順序,也沒有根據順序創建所有數據組的單獨數組。

解決這個問題最優雅的方法是什么? 如果你能引導我朝着正確的方向前進,我將非常感激。

您可以使用Array#reduce並檢查累加器的最后一個元素。

 var array = [{ type: "markup", element: "p", html: "blah" }, { type: "markup", element: "p", html: "blah" }, { type: "markup", element: "p", html: "blah" }, { type: "embeddedVideo", element: "p", html: "embeddedWidget" }, { type: "markup", element: "p", html: "blah" }], grouped = array.reduce((r, o, i, a) => { var last = r[r.length - 1]; if (!last || last[0].type !== o.type) { r.push([o]); } else { last.push(o); } return r; }, []); console.log(grouped); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

我知道for並不像很酷reduce ,但它肯定是更具可讀性:

 const result = [[]];
 let current = result[0], currentType = articleBody[0].type;

 for(const content of articleBody) {
   if(content.type === currentType) {
     current.push(content);
   } else {
     result.push(current = [content]);
     currentType = content.type;
  }
}

要使用reduce()執行此操作,您可以只關注最后看到的內容並將新數組推入結果中,如果它不同,則推入倒數第二個子數組。 進行常規循環可能會使眼睛更容易一些。

 let tempArr = [{"type": "markup","element": "p","html": "blah"}, {"type": "markup","element": "p","html": "blah"}, {"type": "markup","element": "p","html": "blah"}, {"type": "embeddedVideo","element": "p","html": "embeddedWidget"}, {"type": "markup","element": "p","html": "blah"},{"type": "markup","element": "p","html": "blah"},] let r = tempArr.reduce((a, c, i, self) => { if (i === 0 || self[i-1].type !== c.type) a.push([]) a[a.length - 1].push(c) return a }, []) console.log(r) 

這是我的版本:)

 const input = [{ "type": "markup", "element": "p", "html": "blah" }, { "type": "markup", "element": "p", "html": "blah" }, { "type": "markup", "element": "p", "html": "blah" }, { "type": "embeddedVideo", "element": "p", "html": "embeddedWidget" }, { "type": "markup", "element": "p", "html": "blah" }]; const property = 'type'; const collection = [[]]; let found = input[0][property]; input.reduce((prev, next) => { if (found === next[property]) { prev.push(next); return prev; } else { collection.push([next]); found = next[property]; return collection[collection.length - 1]; } }, collection[0]); console.log('Collection', collection); 

這個兩步減少功能的說明:

  1. 如果類型與前一個條目不匹配或者沒有上一個條目,則將新行推入累加器。

  2. 將當前對象添加到最新行。

 const data = [{ "type": "markup", "element": "p", "html": "blah" }, { "type": "markup", "element": "p", "html": "blah" }, { "type": "markup", "element": "p", "html": "blah" }, { "type": "embeddedVideo", "element": "p", "html": "embeddedWidget" }, { "type": "markup", "element": "p", "html": "blah" }, { "type": "markup", "element": "p", "html": "blah" }, ]; const result = data.reduce((a, e) => { if (!a[0] || e.type !== a[a.length-1].type) { a.push([]); } a[a.length-1].push(e); return a; }, []); console.log(result); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM