Álvaro
Álvaro

Reputation: 2588

Add / Overwrite an object in an array

I am trying to overwrite an object in an array if the title property exists, otherwise just push it to the array. I found two approaches and I wonder which one is the preferred one.

Performance is not really an issue but I wonder whether mutability could be, or just there is a better way to do this altogether.

On this snippet I am using a for loop to edit the original array:

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 overwrite
// e.g. const inputTitle = 'CCC'
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)

Here I am using high order functions and spread to do the same:

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 overwrite
// e.g. const inputTitle = 'CCC'
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)

In the real task I am reading the data array from a json file with node and writing the changes back to it.

Upvotes: 3

Views: 5053

Answers (3)

trincot
trincot

Reputation: 350300

If this is a common use case that you will execute several times on the same data structure, then you are better off with a plain object keyed by title, as then the operation is trivial. You can still keep the title also as a property as you had it.

const data = {
  AAA: {
    title: 'AAA',
    people: [ 'John', 'Megan',]
  },
  BBB: {
    title: 'BBB',
    people: [ 'Emily', 'Tom']
  }
};

const title = 'AAA';
const people = ['Peter', 'Jane'];

data[title] = { title, people };  // yes, it's that simple then...

console.log(data);

If you really need the array structure, then you could consider to switch temporarily, then do all the manipulation, and then come back to the original format:

let data = [
  {
    title: 'AAA',
    people: [ 'John', 'Megan',]
  },
  {
    title: 'BBB',
    people: [ 'Emily', 'Tom']
  }
];

const title = 'AAA';
const people = ['Peter', 'Jane'];

// switch to other data structure...
let map = Object.fromEntries(data.map(o => [o.title, o]));

// Manipulate
map[title] = { title, people };

// ...and back:
data = Object.values(map);

console.log(data);

Upvotes: 4

ikiK
ikiK

Reputation: 6532

let newdata = {title: 'AAA',people: [ 'Peter', 'Jane']}
//Create new object 

data.find(c => c.title === newdata.title) !== undefined 
// if title data from new object is find in old
? data.find(c => c.title === newdata.title).people=newdata.people
// change data
 : data.push(newdata)
// in not push it as new

const data = [
  {
    title: 'CCC',
    people: [ 'John', 'Megan']
  },{
    title: 'BBB',
    people: [ 'Emily', 'Tom']
  }
]


let newdata = {title: 'AAA',people: [ 'Peter', 'Jane']}

data.find(c => c.title === newdata.title) !== undefined ? data.find(c => c.title === newdata.title).people=newdata.people : data.push(newdata)

console.log(data)

Upvotes: 1

equt
equt

Reputation: 312

If only the matched items need to be updated, maybe a single forEach could solve this problem.

const data = [
  {
    title: 'AAA',
    people: [ 'John', 'Megan',]
  },{
    title: 'BBB',
    people: [ 'Emily', 'Tom']
  }
]

const inputTitle = 'AAA'
const inputPeople = ['Peter', 'Jane']

data.forEach(({ title }, index) => title === inputTitle ? data[index].people = inputPeople : null)

console.log(data)

Upvotes: 0

Related Questions