Scr*_*ode 17 javascript arrays
我有下面的对象数组,
var data = [
{
label: "Book1",
data: "US edition"
},
{
label: "Book1",
data: "UK edition"
},
{
label: "Book2",
data: "CAN edition"
}
];
Run Code Online (Sandbox Code Playgroud)
我想基于属性'label'合并重复的对象,以便最终输出如下所示,
var data = [
{
label: "Book1",
data: ["US edition", "UK edition"] //data attribute is merged
},
{
label: "Book2",
data: "CAN edition"
}
];
Run Code Online (Sandbox Code Playgroud)
有人可以帮我确定方法吗?
T.J*_*der 18
我可能会循环使用filter
,沿着这些线跟踪我之前看到的对象的地图(编辑以反映您同意是的,(entry).data
总是使数组成为有意义):
var seen = {};
data = data.filter(function(entry) {
var previous;
// Have we seen this label before?
if (seen.hasOwnProperty(entry.label)) {
// Yes, grab it and add this data to it
previous = seen[entry.label];
previous.data.push(entry.data);
// Don't keep this entry, we've merged it into the previous one
return false;
}
// entry.data probably isn't an array; make it one for consistency
if (!Array.isArray(entry.data)) {
entry.data = [entry.data];
}
// Remember that we've seen it
seen[entry.label] = entry;
// Keep this one, we'll merge any others that match into it
return true;
});
Run Code Online (Sandbox Code Playgroud)
在ES6环境中,我会使用seen = new Map()
而不是seen = {}
.
注意:Array.isArray
由ES5定义,因此一些相当老的浏览器(如IE8)将无法使用它.它可以轻松地进行垫片/聚合填充,但是:
if (!Array.isArray) {
Array.isArray = (function() {
var toString = Object.prototype.toString;
return function(a) {
return toString.call(a) === "[object Array]";
};
})();
}
Run Code Online (Sandbox Code Playgroud)
旁注:即使我没有看到两个值,我也可能总是创建 (我们现在已经完成了这个.)entry.data
一个数组,因为一致的数据结构更容易处理.我之前没有这样做,因为data
当只有一个匹配的条目时,你的最终结果显示只是一个字符串.
实例(ES5版):
var data = [
{
label: "Book1",
data: "US edition"
},
{
label: "Book1",
data: "UK edition"
},
{
label: "Book2",
data: "CAN edition"
}
];
snippet.log("Before:");
snippet.log(JSON.stringify(data, null, 2), "pre");
var seen = {};
data = data.filter(function(entry) {
var previous;
// Have we seen this label before?
if (seen.hasOwnProperty(entry.label)) {
// Yes, grab it and add this data to it
previous = seen[entry.label];
previous.data.push(entry.data);
// Don't keep this entry, we've merged it into the previous one
return false;
}
// entry.data probably isn't an array; make it one for consistency
if (!Array.isArray(entry.data)) {
entry.data = [entry.data];
}
// Remember that we've seen it
seen[entry.label] = entry;
// Keep this one, we'll merge any others that match into it
return true;
});
snippet.log("After:");
snippet.log(JSON.stringify(data, null, 2), "pre");
Run Code Online (Sandbox Code Playgroud)
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Run Code Online (Sandbox Code Playgroud)
小智 7
尝试使用以下方法,它可以找到并且很短
var data = [
{
label: "Book1",
data: "US edition"
},
{
label: "Book1",
data: "UK edition"
},
{
label: "Book2",
data: "CAN edition"
}
];
const result = Array.from(new Set(data.map(s => s.label)))
.map(lab => {
return {
label: lab,
data: data.filter(s => s.label === lab).map(edition => edition.data)
}
})
console.log(result);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6483 次 |
最近记录: |