Поиск элемента в массиве на основе другого массива и изменение свойства - PullRequest
0 голосов
/ 28 мая 2019

У меня есть два массива таких объектов:

const officers: any[] = [
  { id: 20, name: 'Captain Piett' },
  { id: 24, name: 'General Veers' },
  { id: 56, name: 'Admiral Ozzel' },
  { id: 88, name: 'Commander Jerjerrod' }
];

const searchAndChangeFor: any[] = [
  { id: 56, name: 'New Name', additionalData: 1 },
];

Я хочу найти элементы из searchAndChangeFor в officers и изменить содержимое.Обычно, если у меня есть один элемент, я делаю это:

officers.map((item) => {
    // I want to modify id: 56 and update officers here.
    item.id === 56 ? { ...item, name: 'Change name for 56' } : item
}); 

Но мне нужно искать по массиву не один элемент, поэтому я пробовал это, но не удалось:

officers.map((item) => {
   searchAndChangeFor.find((item2) => {
       item.id === item2.id? { ...item, name: 'Change name for 56' } : item
   }); 
}); 

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

  { id: 20, name: 'Captain Piett' },
  { id: 24, name: 'General Veers' },
  { id: 56, name: 'New Name', additionalData: 1 },
  { id: 88, name: 'Commander Jerjerrod' }

Сходит с ума с массивом.Как я могу найти элементы в officers на основе searchAndChangeFor и изменить его имя?Я также хочу сохранить все остальные имеющиеся вещи у офицеров.

Ответы [ 6 ]

3 голосов
/ 28 мая 2019

Вы могли бы map массив офицеров. Получите объект с тем же id в searchAndChangeFor, используя find. Объедините их, используя синтаксис распространения

Если вы просто хотите объединиться, вы можете просто сделать

return { ...item, ...searchAndChangeFor.find(o => o.id === item.id) } 

Но, если вы хотите добавить новые свойства, когда совпадение найдено, вы можете условно вернуть, как показано ниже:

const officers=[{id:20,name:'Captain Piett'},{id:24,name:'General Veers'},{id:56,name:'Admiral Ozzel'},{id:88,name:'Commander Jerjerrod'}],
    searchAndChangeFor = [{id:56,name:'New Name',additionalData:1},];
    
const output = officers.map(item => {
  const found = searchAndChangeFor.find(o => o.id === item.id);
  if (found)
    return { ...item, ...found, newProperty: 'value' }
  else
    return item;
})

console.log(output)

Другой вариант - клонировать массив officers, чтобы избежать мутации, и вместо этого перебрать searchAndChangeFor (так как это меньший массив)

const officers=[{id:20,name:'Captain Piett'},{id:24,name:'General Veers'},{id:56,name:'Admiral Ozzel'},{id:88,name:'Commander Jerjerrod'}],
    searchAndChangeFor = [{id:56,name:'New Name',additionalData:1},],
    output = [...officers];

searchAndChangeFor.forEach(s => {
  const index = officers.findIndex(o => o.id === s.id);
  output[index] = Object.assign({}, output[index], s)
})

console.log(output)
1 голос
/ 28 мая 2019

Предполагая, что вы хотите сохранить все свойства объектов officers и searchAndChangeFor:

const officers = [
    { id: 20, name: 'Captain Piett' },
    { id: 24, name: 'General Veers' },
    { id: 56, name: 'Admiral Ozzel', admiralSince: 2008 },
    { id: 88, name: 'Commander Jerjerrod' }
];

const searchAndChangeFor = [
    { id: 56, name: 'New Name', additionalData: 1 },
];

const newOfficers = officers.map(officer => {
    const changedOfficer = searchAndChangeFor.find(changedOfficer => changedOfficer.id === officer.id)
    return changedOfficer ? { ...officer, ...changedOfficer } : officer;
});

console.log(newOfficers);
1 голос
/ 28 мая 2019

find ожидает логического ответа, когда он принимает значение true, возвращает элемент, для которого было возвращено значение true, вы пытаетесь изменить элемент непосредственно в теле функции обратного вызова find.Это не то, что вам нужно сделать, вы просто хотите изменить значение, в котором существует идентификатор в вашем массиве searchAndChangeFor.

const ids = searchAndChangeFor.map((rel) => rel.id);
const changed = officers.map((item) => ids.includes(item.id) ?
    {{ Item mutation logic here }} :
    item);
1 голос
/ 28 мая 2019

Вы можете найти предмет и изменить его с найденным именем или вернуть товар без изменений.

const
    officers = [{ id: 20, name: 'Captain Piett' }, { id: 24, name: 'General Veers' }, { id: 56, name: 'Admiral Ozzel' }, { id: 88, name: 'Commander Jerjerrod' }],
    searchAndChangeFor = [{ id: 56, name: 'New Name', additionalData: 1 }],
    result = officers.map((item) => {
        let temp = searchAndChangeFor.find((item2) => item.id === item2.id); 
        return temp ? { ...item, name: temp.name } : item;
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 28 мая 2019

вы можете найти товар и, если он найден, изменить имя и вернуть измененный товар или просто вернуть товар (без изменений)

officers.map((item) => {
   searchAndChangeFor.find((item2) => {
       if (item.id === item2.id) {
          return { ...item, name: 'Change name for 56' } 
       }
   }) || item; 
});
0 голосов
/ 28 мая 2019

Проблема с вашим кодом в том, что .map ожидает, что вы вернете значение, которое будет сохранено в результирующем массиве, тогда как вы ничего не возвращаете.

Вы можете сохранить массив всех идентификаторов searchAndChangeFor. Это будет вычислено только один раз, поэтому оно будет эффективным, и его будет легче сравнивать с officer.id в .map.

const officers = [
  { id: 20, name: 'Captain Piett' },
  { id: 24, name: 'General Veers' },
  { id: 56, name: 'Admiral Ozzel' },
  { id: 88, name: 'Commander Jerjerrod' }
];

const searchAndChangeFor = [
  { id: 56, name: 'Admiral Ozzel' },
];

const allIDsToChange = searchAndChangeFor.map(el => el.id);
const newOfficers = officers.map((item) => allIDsToChange.includes(item.id) ? { ...item,
  name: 'Change name for 56'
} : item);

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