将对象数组简化为键值对映射,保留值数组中的重复条目



我需要减少对象数组,但要减少对象中的特定key属性,并将具有相同key值的所有对象放入关联的value数组中的数组中。

我需要的一个例子:

对象

var obj1 = {
name: "server1",
type: "http",
port: "8080"
}
var obj2 = {
name: "server2",
type: "https",
port: "8443"
}
var obj3 = {
name: "server3",
type: "http",
port: "80"
}
// Place objects in an array (as interm step)
var array = [obj1, obj2, obj3];

使用上面的代码,我尝试了

var map = new Map(array.map(server => [server.type, server]));

但这最终给了我:

0: {"http" => Object}
key: "http"
value:
name: "server3"
port: "80"
type: "http"
1: {"https" => Object}
key: "https"
value:
name: "server2"
port: "8443"
type: "https"

但我需要的是

0: {"http" => Object}
key: "http"
value:[ 
{
name: "server1"
port: "8080"
type: "http"
},
{
name: "server3"
port: "80"
type: "http"
},
1: {"https" => Object}
key: "https"
value:
name: "server2"
port: "8443"
type: "https"

所以我可以遍历每个type,找到所有唯一值,以此为类型创建每个对象的列表,然后将其添加到地图中,但对于一个简单的任务来说似乎太多了。

有没有更快/更方便的方法来缩短这个时间?

我不确定地图在这里是否合适。您可以使用一个简单的forEach并检查数组中是否已存在当前键。如果没有,则使用当前项创建一个新对象并检查下一个对象。

像这样:

var obj1 = {
name: "server1",
type: "http",
port: "8080"
}
var obj2 = {
name: "server2",
type: "https",
port: "8443"
}
var obj3 = {
name: "server3",
type: "http",
port: "80"
}
// Place objects in an array (as interm step)
var array = [obj1, obj2, obj3];
let output = {};
array.forEach((item) => {
// the item does not exists, we create it.
if(!output[item.type]) {
output[item.type] = {key: item.type, value: []};
}
// in either case, we push the current item in the value.
// of the current output key.
output[item.type].value.push(item);
});
// we are using Object.values() because we do not want the keys
// used to generate the output.
console.log(Object.values(output));

这是reduce()的完美用例。 格式为:

arr.reduce(callback( accumulator, currentValue[, index[, array]] )[, initialValue])

我们将initialValue参数设置为空对象({}(。 然后,我们的回调函数将获取数组中的每个项目,并将其添加到我们分类对象中的正确数组中。见下文:

var obj1 = {
name: "server1",
type: "http",
port: "8080"
}
var obj2 = {
name: "server2",
type: "https",
port: "8443"
}
var obj3 = {
name: "server3",
type: "http",
port: "80"
}
// Place objects in an array (as interm step)
var array = [obj1, obj2, obj3];
const result = array.reduce((categorisedObjs, currentItem) => {
// If the key does not yet exist in our object then create it
// and initialize it with an empty array
if (!categorisedObjs[currentItem.type]) categorisedObjs[currentItem.type] = []
// Add the object to the correct array
categorisedObjs[currentItem.type].push(currentItem);
// Return the categorised objects for the next iteration
return categorisedObjs;
}, {});
console.log(JSON.stringify(result, true, 2));

这将产生所需的确切结果,并且相对容易理解:

{
"http": [
{
"name": "server1",
"type": "http",
"port": "8080"
},
{
"name": "server3",
"type": "http",
"port": "80"
}
],
"https": [
{
"name": "server2",
"type": "https",
"port": "8443"
}
]
}

我认为这就是你实现它的方式

var array = [obj1, obj2, obj3];
var newarray = [];
$.each(array, function( index, value ) {
if(!newarray[value.type]) {
newarray[value.type] = {data:[]};
}
newarray[value.type].data.push(value);
});
console.log(newarray);

最新更新