javascript - уменьшить массив объектов до пары пар ключ-значение, сохранив повторяющиеся записи в массиве значений - PullRequest
0 голосов
/ 23 января 2020

Мне нужно уменьшить массив объектов, но уменьшить указанное свойство c 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"

Так что я могу go через каждые type найдите все уникальные значения, создайте списки каждого объекта с этим типом, а затем добавьте его на карту, но это кажется слишком сложным для простой задачи.

Есть ли более быстрый / более удобный способ сократить это?

Ответы [ 3 ]

3 голосов
/ 23 января 2020

Я не уверен, что карта была бы подходящей функцией здесь. Вы можете использовать простой 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));
1 голос
/ 23 января 2020

Я думаю, вот как вы можете достичь этого

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);
1 голос
/ 23 января 2020

Это идеальный вариант использования для 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"
    }
  ]
}
...