Как изменить идентификатор элемента в словаре на основе определенной логики

#javascript

Вопрос:

Я хочу изменить имя идентификатора, если он имеет 2 цвета.

Мой упрощенный список выглядит так:

 var myList = [{'ID': 'ES', 'volume': 1, 'color': 'red'},
 {'ID': 'ES', 'volume': 2, 'color': 'red'},
 {'ID': 'ES', 'volume': 1, 'color': 'green'},
 {'ID': 'HH', 'volume': 1, 'color': 'red'},
 {'ID': 'HR', 'volume': 4, 'color': 'green'},
 {'ID': 'HR', 'volume': 4, 'color': 'red'},
{'ID': 'ES', 'volume': 1, 'color': 'red'}]
 

Логика: в случае, если есть 2 идентификатора, которые имеют разные цвета — измените идентификатор красного на __СТАРЫЙ.

пример: в списке выше идентификатор » ES » имеет как зеленый, так и красный цвета — поэтому для красного измените ES на ES__СТАРЫЙ.

ожидаемый результат:

 var myList = [{'ID': 'ES__OLD', 'volume': 1, 'color': 'red'},
 {'ID': 'ES__OLD', 'volume': 2, 'color': 'red'},
 {'ID': 'ES', 'volume': 1, 'color': 'green'},
 {'ID': 'HH', 'volume': 1, 'color': 'red'},
 {'ID': 'HR', 'volume': 4, 'color': 'green'},
 {'ID': 'HR__OLD', 'volume': 4, 'color': 'red'},
{'ID': 'ES__OLD', 'volume': 1, 'color': 'red'}]
 

Что я пробовал:

 var keys = new Set();
myList.forEach(i=>{
  
  keys.add(i['ID'] ' ' i['color'])
})
 

Результат:

 0: "ES red"
1: "ES green"
2: "HH red"
3: "HR green"
4: "HR red"
 

ожидаемый

Проблема: теперь я должен исключить тех, у кого есть только один цвет (в примере HH), а затем повторить myList и внести изменения.

Есть ли лучший способ?

Комментарии:

1. Ваша логика неясна. Пожалуйста, укажите ваш ожидаемый конечный результат.

Ответ №1:

Надеюсь, это то решение, которое вы ищете.

Логические

  • Пройдите по узлам массива myList
  • Проверьте, есть ли в массиве myList другой узел с таким же ID
  • Если узел с таким же ID существует и цвет этого узла является red обновлением ID узла.
  • Вставьте новый узел в accumulator массив.

Рабочий Пример

 var myList = [
  { 'ID': 'ES', 'volume': 1, 'color': 'red' },
  { 'ID': 'ES', 'volume': 2, 'color': 'red' },
  { 'ID': 'ES', 'volume': 1, 'color': 'green' },
  { 'ID': 'HH', 'volume': 1, 'color': 'red' },
  { 'ID': 'HR', 'volume': 4, 'color': 'green' },
  { 'ID': 'HR', 'volume': 4, 'color': 'red' },
  { 'ID': 'ES', 'volume': 1, 'color': 'red' }
];
const result = myList.reduce((acc, curr, index) => {
  console.log(curr, index);
  const newNode = { ...curr };
  const matchingNodes = myList.filter((node) => node.ID === curr.ID);
  if (matchingNodes.length > 1 amp;amp; newNode.color === 'red') {
    newNode.ID  = '_OLD';
  }
  acc.push(newNode);
  return acc;
}, []);
console.log(result); 

Если вы не хотите исключать тех, у кого есть только один цвет, вам нужно проверить длину соответствующего списка узлов, прежде чем отправлять его в накопитель.

Рабочий Пример

 var myList = [
  { 'ID': 'ES', 'volume': 1, 'color': 'red' },
  { 'ID': 'ES', 'volume': 2, 'color': 'red' },
  { 'ID': 'ES', 'volume': 1, 'color': 'green' },
  { 'ID': 'HH', 'volume': 1, 'color': 'red' },
  { 'ID': 'HR', 'volume': 4, 'color': 'green' },
  { 'ID': 'HR', 'volume': 4, 'color': 'red' },
  { 'ID': 'ES', 'volume': 1, 'color': 'red' }
];
const result = myList.reduce((acc, curr, index) => {
  console.log(curr, index);
  const newNode = { ...curr };
  const matchingNodes = myList.filter((node) => node.ID === curr.ID);
  if (matchingNodes.length > 1 amp;amp; newNode.color === 'red') {
    newNode.ID  = '_OLD';
  }
  if (matchingNodes.length > 1) {
    acc.push(newNode);
  }
  return acc;
}, []);
console.log(result);