javascript - 将对象数组缩减为键值对映射,在值数组中保留重复项

javascript - reduce array of objects to a key value pair map retaining duplicate entries in a value array

我需要减少一个对象数组,但是减少对象中特定的 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,找到所有唯一值,创建每个对象的列表并将其作为类型,然后将其添加到地图中,但这对于一个简单的任务来说似乎太多了。

有没有faster/more方便的方法来缩短它?

我不确定地图是否适合这里的功能。您可以使用简单的 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);