![](/img/trans.png)
[英]Trying to split array into specified amount of subarrays in javascript
[英]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);
这个两步减少功能的说明:
如果类型与前一个条目不匹配或者没有上一个条目,则将新行推入累加器。
将当前对象添加到最新行。
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.