L oop над массивом объектов, удалите дубликаты, удалите один и назначьте логическое значение оригиналу - PullRequest
0 голосов
/ 10 июля 2020

У меня есть следующий образец arr:

const fetchedArr = [
{ id: "3cc74658-a984-4227-98b0-8c28daf7d3d4", type: a },
{ id: "9b96e055-dc2a-418c-9f96-ef449e34db60", type: a },
{ id: "9b96e055-dc2a-418c-9f96-ef449e34db60", type: b }
]

Мне нужен следующий результат:

const arr = [
{ id: "3cc74658-a984-4227-98b0-8c28daf7d3d4", type: a, checked: true },
{ id: "9b96e055-dc2a-418c-9f96-ef449e34db60", type: a, checked: true, hasPair: true }
]

У меня есть следующий фрагмент, который работает

 const newLegendItems = fetchedArr
      .reduce((acc, curr, idx, arr) => {
        const singleComponentLines = arr.filter((g) => g.id === curr.id);
        const exists = !!acc.find((x) => x.id === curr.id);
        if (!exists) {
          if (singleComponentLines.length === 2 && singleComponentLines.includes(curr)) {
            acc[idx] = {...curr, hasPair: true};
          } else {
            acc[idx] = curr;
          }
        }
        return acc;
      }, [])
      .map((l) => ({ ...l, checked: true }));

, но я думал, есть ли более простой способ добиться этого? Я должен уточнить, что в fetchedArr type не имеет значения, и что не будет более двух одинаковых идентификаторов, отсюда и моя идея для singleComponentLines.length === 2.

Ответы [ 3 ]

1 голос
/ 10 июля 2020

Как это?

const fetchedArr = [
{ id: "3cc74658-a984-4227-98b0-8c28daf7d3d4", type: "a" },
{ id: "9b96e055-dc2a-418c-9f96-ef449e34db60", type: "a" },
{ id: "9b96e055-dc2a-418c-9f96-ef449e34db60", type: "b" }
];

let result = fetchedArr.reduce((acc,v) => {
   //first i need to check if i already have an element with the same ID in my accumulator. i either get -1 for not found or the index where the element is.
   let i = acc.findIndex(el => el.id === v.id);
   
   if(i !== -1) {
      //if there is an element then access the element in the array with a[i] and add a new property to the object with ["hasPair"] and set it to true
      acc[i]["hasPair"] = true;
      
      return acc;
   }

   //in case i = -1 what means not found
   return [...acc, {...v, checked: true}];
},[])

console.log(result);
0 голосов
/ 10 июля 2020

Я предпочитаю использовать карту для такого рода вещей, поскольку она обеспечивает большую читабельность IMO.

  1. Начните с проверки, есть ли она у нас
  2. Обновите наш компонент и добавьте его в Карта

Единственная «сложность» в том, что нам нужно перебрать .values(), чтобы получить наши обновленные компоненты, но благодаря оператору распространения это довольно просто.

const components = [
  { id: "3cc74658-a984-4227-98b0-8c28daf7d3d4", type: 'a' },
  { id: "9b96e055-dc2a-418c-9f96-ef449e34db60", type: 'a' },
  { id: "9b96e055-dc2a-418c-9f96-ef449e34db60", type: 'b' },
];

const newLegendItems = components
  .reduce((acc, component) => {
    if (acc.has(component.id)) {
      acc.get(component.id)['hasPair'] = true;
    } else {
      acc.set(component.id, { ...component, checked: true });
    }

    return acc;
  }, new Map());
  
  console.log([...newLegendItems.values()]);
0 голосов
/ 10 июля 2020

Я не совсем понимаю ваш вопрос, но он должен помочь:

const result = [{
    id: "3cc74658-a984-4227-98b0-8c28daf7d3d4",
    type: 'a'
  },
  {
    id: "9b96e055-dc2a-418c-9f96-ef449e34db60",
    type: 'a'
  },
  {
    id: "9b96e055-dc2a-418c-9f96-ef449e34db60",
    type: 'b'
  }
].reduce((acc, el) => {
  const idx = acc.findIndex(it => it.id === el.id);
  if (idx > -1) {
    acc[idx] = { ...acc[idx],
      hasPair: true
    }
  } else {
    acc.push({ ...el,
      checked: true
    });
  }

  return acc;
}, []);

console.log(result)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...