Javascript: объединение / переименование похожих объектов в массиве по одному ключу / значению - PullRequest
0 голосов
/ 02 ноября 2018

С этим примером массива объектов:

[{
   "Element ID": "299",
   "Element Name": "Manager",
   "Scale ID": "IM",
   "Data Value": "3.5"
},
{
   "Element ID": "299",
   "Element Name": "Manager",
   "Scale ID": "LV",
   "Data Value": "3"
},
{
   "Element ID": "300",
   "Element Name": "FinTech",
   "Scale ID": "IM",
   "Data Value": "1.75"
},
{
   "Element ID": "300",
   "Element Name": "FinTech",
   "Scale ID": "LV",
   "Data Value": "1.38"`
}]

Я написал этот код для объединения дубликатов объектов Element ID и переименования некоторых элементов:

let p = {};
const output = input
  .map(s => {
    if (_.isEmpty(p)) {
      p = s;
      return {};
    }
    if (p['Element ID'] !== s['Element ID']) return {};
    const result = {
      name: s['Element Name'],
      id: s['Element ID'],
      importance:
        p['Scale ID'] === 'IM'
          ? p['Data Value']
          : s['Scale ID'] === 'IM'
            ? s['Data Value']
            : null,
      level:
        p['Scale ID'] === 'LV'
          ? p['Data Value']
          : s['Scale ID'] === 'LV'
            ? s['Data Value']
            : null,
    };
    p = {};
    return result;
  })
  .filter(n => Object.keys(n).length);

Итак, теперь выводится желаемый формат:

[{
   "name": "Manager",
   "id": "299",
   "importance": "3.5",
   "level": "3"
},
{
   "name": "FinTech",
   "id": "300",
   "importance": "1.75",
   "level": "1.38"
}]

Это сложный метод, который не работает, если массив входных объектов не содержит ровно два похожих объекта в массиве. Есть ли лучший способ через lodash, .reduce() или аналогичный, я не рассматриваю?

1 Ответ

0 голосов
/ 02 ноября 2018

Попробуйте это:

const resultObject = originalArray.reduce((result, element) => {
  const id = element["Element ID"];
  const resultElement = result[id] || { 
    id,
    name: element["Element Name"],
  };

  switch (element["Scale ID"]) {
    case "LV":
      resultElement.level = element["Data Value"] || null;
      break;
    case "IM":
      resultElement.importance = element["Data Value"] || null;
      break;
  }


  return {
    ...result,
    [id]: resultElement,
  }
}, {});

const resultArray = Object.keys(resultObject).reduce((result, key) => ([
  ...result,
  {
    "id": key,
    ...resultObject[key],
  }
]), []);

originalArray это ваши данные.

Вы можете улучшить это, переместив ключи в константы. Просто попытайтесь сделать ваш код читабельным. Алгоритм не так уж сложен. Воздержитесь от использования библиотек для простых задач, подобных этой. Javascript уже очень мощный.

...