Добавить / перезаписать объект в массиве

Я пытаюсь перезаписать объект в массиве, если 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 ответ
1

Из небольшого обзора;

  • Первый фрагмент не работает, попробуйте inputTitle="BBB"

  • По сути, вы делаете 2 вещи

    1. Найдите возможное совпадение
    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"]));

  • Спасибо, это выглядит действительно красиво, мне действительно нужно клонировать данные?

    — Альваро

  • 1

    Не все, но для того, чтобы тест оставался чистым, я клонировал данные.

    — кролик

  • Я не понимаю одного: если target это совершенно новый массив. data массив изменяется, когда вы делаете forEach на target? Это из-за того, что неглубокий клон фильтра не изменяет массив?

    — Альваро


  • 1

    target представляет собой массив объектов, который можно рассматривать как указатели на объекты в data

    — кролик

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *