Как группировать объекты в соответствии со свойством

#javascript #node.js #logic #lodash #backend

#javascript #node.js #Логические #Lodash #серверная часть

Вопрос:

Надеюсь, кто-нибудь сможет мне помочь,

Ситуация: я разрабатываю отчет об объекте, в котором я выбираю всех своих клиентов с их идентификатором unit_id (unit_id — это связь с unit, где они могут быть расположены), и этот выбор представляет собой массив массив объектов, и у меня возникают проблемы с тем, как группировать объекты в соответствии с одним конкретным свойствому меня есть массив, подобный:

 const clients = [
  [
    {
      ID: 1,
      NAME: 'John Doe',
      UNITS: ['02'],
    }
  ],
  [
    {
      ID: 2,
      NAME: 'Jane Doe',
      UNITS: ['01', '02'],
    }
  ],
  [
    {
      ID: 3,
      NAME: 'Doe John',
      UNITS: ['50', '15'],
    }
  ],
  [
    {
      ID: 4,
      NAME: 'Doe Jane',
      UNITS: ['30'],
    }
  ],
  [
    {
      ID: 5,
      NAME: 'Doe Jane',
      UNITS: ['15'],
    }
  ],
]
  

Проблема:
Мне нужно сгруппировать каждого человека с одной и той же «ЕДИНИЦЕЙ«, но у меня не может быть нескольких групп с одинаковым «ИДЕНТИФИКАТОРОМ ЕДИНИЦЫ«, который у меня есть в одной группе, я ожидаю результата, подобного:

 const unitGroups = [
  [
    {
      UNIT_IDS: ['01', '02'],
      CLIENTS: [
        {
          ID: 1,
          NAME: 'John Doe',
        }, 
        {
          ID: 2,
          NAME: 'Jane Doe',
        }
      ]
    }
  ],
  [
    {
      UNIT_IDS: ['50', '15'],
      CLIENTS: [
        {
          ID: 3,
          NAME: 'Doe John',
        },
        {
          ID: 5,
          NAME: 'Doe Jane',
        }
      ]
    }
  ],
  [
    {
      UNIT_IDS: ['30'],
      CLIENTS: [
        {
          ID: 4,
          NAME: 'Doe Jane',
        }
      ]
    }
  ]
]
  

Ответ №1:

Вы можете использовать reduce для достижения результата. Вот реализация:

 const clients = [ [ { ID: 1, NAME: 'John Doe', UNITS: ['02'], } ], [ { ID: 2, NAME: 'Jane Doe', UNITS: ['01', '02'], } ], [ { ID: 3, NAME: 'Doe John', UNITS: ['50', '15'], } ], [ { ID: 4, NAME: 'Doe Jane', UNITS: ['30'], } ], [ { ID: 5, NAME: 'Doe Jane', UNITS: ['15'], } ]];

const result = clients.reduce((a,e)=>{
   e.forEach(({UNITS, ...rest})=>{
    const getIndex = a.findIndex(p=>p.UNIT_IDS.some(b=>UNITS.some(c=>c===b)));
    if(getIndex===-1){
       const newData = {UNIT_IDS:UNITS, CLIENTS:[].concat(rest)};
       a.push(newData);
       } else {
       a[getIndex].UNIT_IDS = [...new Set([...a[getIndex].UNIT_IDS, ...UNITS])];
       a[getIndex].CLIENTS = [...a[getIndex].CLIENTS, rest]
       }
    })
  return a;
},[]);

console.log(result);  

Ответ №2:

 const intersection = (array1, array2) =>
  array1.filter((value) => array2.includes(value));

const results = [];

for (const { ID, NAME, UNITS } of clients.flat()) {
  const contain = results.find(({ UNIT_IDS }) =>
    intersection(UNIT_IDS, UNITS).length
  );

  if (contain) {
    contain.CLIENTS.push({ ID, NAME });

    if (UNITS.length > contain.UNIT_IDS.length) {
      contain.UNIT_IDS = UNITS;
    }

    continue;
  }

  results.push({
    UNIT_IDS: UNITS,
    CLIENTS: [
      { ID, NAME },
    ],
  });
}

console.log(results.map((group) => [group]));