Я пытаюсь перезаписать объект в массиве, если title свойство существует, в противном случае просто поместите его в массив. Я нашел два подхода, и мне интересно, какой из них предпочтительнее.
Производительность на самом деле не является проблемой, но мне интересно, может ли быть изменчивость, или просто есть лучший способ сделать это вообще.
В этом фрагменте я использую цикл for для редактирования исходного массива:
const data = [
{
title: 'AAA',
people: [ 'John', 'Megan',]
},{
title: 'BBB',
people: [ 'Emily', 'Tom']
}
]
// If inputTitle is not on any of data's title it will append not overwritte
const inputTitle="AAA"
const inputPeople = ['Peter', 'Jane']
for (const obj of data) {
if (obj.title === inputTitle) {
obj.people = inputPeople
break
} else {
data.push({
title: inputTitle,
people: inputPeople
})
break
}
}
console.log(data)Здесь я использую функции высокого порядка и спред, чтобы сделать то же самое:
const data = [
{
title: 'AAA',
people: [ 'John', 'Megan',]
},{
title: 'BBB',
people: [ 'Emily', 'Tom']
}
]
// If inputTitle is not on any of data's title it will append not overwritte
const inputTitle="AAA"
const inputPeople = ['Peter', 'Jane']
let res = []
if (data.some(({ title }) => title === inputTitle)) {
res = data.map(obj => {
if (obj.title === inputTitle)
obj.people = inputPeople
return obj
})
} else {
res = [...data, { title: inputTitle, people: inputPeople}]
}
console.log(res)В реальной задаче я читаю data массив из json-файла с узлом и записывает в него изменения.
1 ответ
Из небольшого обзора;
Первый фрагмент не работает, попробуйте
inputTitle="BBB"По сути, вы делаете 2 вещи
- Найдите возможное совпадение
- Обновите совпадение или вставьте данные
В идеале это делается в 1 «петлю».
Если вас не слишком заботит производительность, я бы выбрал функциональный подход.
Это мое встречное предложение (изменяющее данные)
const data = [
{
title: 'AAA',
people: [ 'John', 'Megan',]
},{
title: 'BBB',
people: [ 'Emily', 'Tom']
}
]
function mergePeople(data, title, people){
const target = data.filter(record=>record.title===title);
if(target.length){
target.forEach(record => record.people = people);
}else{
data.push({title, people});
}
return data;
}
function quickClone(o){
return JSON.parse(JSON.stringify(o));
}
console.log(mergePeople(quickClone(data), "AAA", ["Tom", "Jerry"]));
console.log(mergePeople(quickClone(data), "BBB", ["Ben", "Jerry"]));
Спасибо, это выглядит действительно красиво, мне действительно нужно клонировать данные?
— Альваро
Не все, но для того, чтобы тест оставался чистым, я клонировал данные.
— кролик
Я не понимаю одного: если
targetэто совершенно новый массив.dataмассив изменяется, когда вы делаетеforEachнаtarget? Это из-за того, что неглубокий клон фильтра не изменяет массив?— Альваро
targetпредставляет собой массив объектов, который можно рассматривать как указатели на объекты вdata— кролик