jj008
jj008

Reputation: 1093

Filter array of objects then replace

I have an array of objects that I would like to filter, and then return the filtered array but compare with another array to see if it needs to be replaced.

For example, I want to filter allItems by category_id = 2, and then based on the newItems array, I want to return the filtered array but with the update item in newItems (if it exists).

allItems = [
  {
    'id': 1,
    'category_id': 2,
    'text': 'old',
    'child': [
      {
        'id': 2,
        'category_id': 2,
        'text': 'old'
      }
    ]
  },
  {
    'id': 3,
    'category_id': 3,
    'text': 'old'
  }
]


newItems = [
  {
    'id': 2,
    'category_id': 2,
    'text': 'new'
  }
]

So I want to return:

results = [
  {
    'id': 2,
    'category_id': 2,
    'text': 'new'
  },
  {
    'id': 3,
    'category_id': 2,
    'text': 'old'
  },
]

Right now, I have the filtering part but I'm not sure how to compare to another array and replace with the updated item.

return this.allItems.filter( (item) => {
  return item.category_id == 2
})

Upvotes: 1

Views: 8506

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371049

Use filter followed by .map, to replace items (if needed) with the new item:

const allItems = [
  {
    'id': 1,
    'category_id': 1,
    'text': 'old'
  },
  {
    'id': 2,
    'category_id': 2,
    'text': 'old'
  },
  {
    'id': 3,
    'category_id': 2,
    'text': 'old'
  }
];
const newItems = [
  {
    'id': 2,
    'category_id': 2,
    'text': 'new'
  }
];

const newItemsById = newItems.reduce((a, item) => {
  a[item.id] = item;
  return a;
}, {});

const output = allItems
  .filter(({ category_id }) => category_id === 2)
  .map((item) => newItemsById[item.id] ? newItemsById[item.id] : item);
console.log(output);

Also note that your 'id': <number> key-value pairs in your allItems need to be followed by commas, when followed by another key-value pair, for the syntax to be valid.

Upvotes: 2

Related Questions