Преобразование массива объектов на основе ключа - javascript - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь найти наиболее эффективный метод сокращения массива объектов на основе уникального ключа (ключ / значения в этом случае динамически возвращаются). Я пытался комбинировать различные методы, используя concat, map или filter, но мне не повезло.

Исходный массив объектов:

[
  {
    key: "Name",
    value: "John"
  },
  {
    key: "Company",
    value: "Acme"
  },
  {
    key: "Name",
    value: "Jack"
  },
  {
    key: "Name",
    value: "Matt"
  },
  {
    key: "Last",
    value: "Test"
  }
]

Желаемый массив:

[
  {
    key: "Name",
    values: [
      "John",
      "Jack",
      "Matt"
    ]
  },
  {
    key: "Company",
    values: [
      "Acme"
    ]
  },
  {
    key: "Last",
    values: [
      "Test"
    ]
  }
]

Ответы [ 3 ]

1 голос
/ 26 марта 2020

Вы можете использовать reduce для создания нового объекта, используя name в качестве ключей, а затем используйте Object.values для создания необходимого вывода из объекта:

const data = [
  { key: "Name", value: "John" },
  { key: "Company", value: "Acme" },
  { key: "Name", value: "Jack" },
  { key: "Name", value: "Matt" },
  { key: "Last", value: "Test" }
];

const out = Object.values(data.reduce((acc, { key, value }) => {

  // If the key doesn't exist on the object, add it
  // and initialise the value object
  acc[key] = acc[key] || { key, values: [] };

  // Push the value from the current iteration
  // into the values array
  acc[key].values.push(value);

  // Return the accumulator for the next iteration
  return acc;
}, {}));

console.log(out);
1 голос
/ 26 марта 2020

Я думаю, уменьшить является лучшим решением здесь:)

const initialArray = [
  {
    key: "Name",
    value: "John"
  },
  {
    key: "Company",
    value: "Acme"
  },
  {
    key: "Name",
    value: "Jack"
  },
  {
    key: "Name",
    value: "Matt"
  },
  {
    key: "Last",
    value: "Test"
  }
];

const result = initialArray.reduce((acc, obj) => {
   /* try to find object in the result array
      returns index or -1 if object is missing
   */
   const existingIndex = acc.findIndex(item => item.key === obj.key);

   if (existingIndex > -1) {
      /* object already exists, update its values array */
      acc[existingIndex].values.push(obj.value);
      return acc;
   } else {
     /* the key is first encountered, create an object in the result array */
     acc.push({
       key: obj.key,
       values: [obj.value],
     });
     return acc;
   }
}, []); // [] - default value is an empty array

console.log(result);
1 голос
/ 26 марта 2020

Возможно другие пути, но для l oop достаточно простого:

const data = [{
    key: "Name",
    value: "John"
  },
  {
    key: "Company",
    value: "Acme"
  },
  {
    key: "Name",
    value: "Jack"
  },
  {
    key: "Name",
    value: "Matt"
  },
  {
    key: "Last",
    value: "Test"
  }
]

let result = {}

for (const i in data) {
  result[data[i].key] = {
    key: data[i].key,
    values: [
      ...result[data[i].key] ? result[data[i].key].values : [],
      data[i].value
    ]
  }
}

console.log(Object.values(result))
...