javascript—将对象数组简化为键值对映射,在值数组中保留重复项

javascript—将对象数组简化为键值对映射,在值数组中保留重复项,javascript,arrays,maps,mapping,Javascript,Arrays,Maps,Mapping,我需要减少一个对象数组,但要减少对象中特定的键属性,并将具有相同键值的所有对象放置在关联的值数组中的一个数组中 我需要的一个例子: 对象 var obj1 = { name: "server1", type: "http", port: "8080" } var obj2 = { name: "server2", type: "https", port: "8443" } var obj3 = { name: "server3", type: "http",

我需要减少一个对象数组,但要减少对象中特定的
属性,并将具有相同
值的所有对象放置在关联的
数组中的一个数组中

我需要的一个例子:

对象

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"
因此,我可以遍历每个
类型
,找到所有唯一的值,创建每个对象的列表,并将其作为一个类型,然后将其添加到地图中,但这对于一个简单的任务来说似乎太多了


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

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

大概是这样的:

var obj1={
名称:“服务器1”,
键入:“http”,
端口:“8080”
}
变量obj2={
名称:“服务器2”,
键入:“https”,
端口:“8443”
}
变量obj3={
名称:“服务器3”,
键入:“http”,
端口:“80”
}
//将对象放置在阵列中(作为中间步骤)
变量数组=[obj1,obj2,obj3];
让输出={};
array.forEach((项)=>{
//该项不存在,我们将创建它。
如果(!输出[项目类型]){
输出[item.type]={key:item.type,值:[]};
}
//在这两种情况下,我们都将当前项推送到值中。
//当前输出键的。
输出[item.type].value.push(item);
});
//我们使用Object.values()是因为我们不需要这些键
//用于生成输出。

console.log(Object.values(output))这是
reduce()
的完美用例。格式为:

arr.reduce(callback( accumulator, currentValue[, index[, array]] )[, initialValue])
我们将
initialValue
参数设置为空对象(
{}
)。然后,我们的回调函数将获取数组中的每个项,并将其添加到分类对象中的正确数组中。见下文:

var obj1={
名称:“服务器1”,
键入:“http”,
端口:“8080”
}
变量obj2={
名称:“服务器2”,
键入:“https”,
端口:“8443”
}
变量obj3={
名称:“服务器3”,
键入:“http”,
端口:“80”
}
//将对象放置在阵列中(作为中间步骤)
变量数组=[obj1,obj2,obj3];
const result=array.reduce((分类对象,当前项)=>{
//如果键在我们的对象中还不存在,那么就创建它
//并使用空数组初始化它
如果(!categorisedObjs[currentItem.type])categorisedObjs[currentItem.type]=[]
//将对象添加到正确的数组中
CategoriseObjs[currentItem.type].push(currentItem);
//为下一次迭代返回分类对象
返回分类对象;
}, {});

log(JSON.stringify(result,true,2))我想这就是你可以实现它的方法

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);

我不太理解您的代码,有一个未使用的变量
newarray
,您正在尝试访问数组中的字符串键,其键是数字。在OP的问题中没有提到这个库时,您建议使用JQuery。我不想无礼,我只是觉得你的答案需要改进。我已经更新了代码。出于完整性考虑,抱歉粘贴了错误的地图,因为我打算使用
map.forEach()
,所以我使用了
let output=new map()
而不是
let output={}允许我舒适地使用
forEach()