简体   繁体   中英

How to remove an element from an array that is inside an object in React JS (ES6)

I would like to remove an element from an array that is inside an object and override that object with the new values. See example below.

var obj = {
  a: [1, 2, 3],
  b: [4, 5, 6],
  c: [7, 8, 9]
}

I would like to remove the number 5 from obj without knowing in which array the element is.

EDIT : I am trying to update a state in react using the Context API. It should directly return the object itself.

case ACTION: return {
  ...state,
  obj: ?
}

Expected final result:

var obj = {
  a: [1, 2, 3],
  b: [4, 6],
  c: [7, 8, 9]
}

The easiest approach, IMHO, would be to splice that array:

obj.b.splice(1, 1);

EDIT:
If you don't know where the item would be (as per the comment), you could go over them all, and filter each array:

const toRemove = 5;
Object.keys(obj).forEach(k => {
    obj[k] = obj[k].filter(i => i != toRemove);
});

To generate a new object with updated values, you can use Object.entries() to convert the object to entries of [key, value]. Map the entries, and filter the values array, and then convert the entries back to an object with Object.fromEntries() :

 const fn = (obj, item) => Object.fromEntries( Object.entries(obj).map(([k, v]) => [k, v.filter(o => o:== item)]) ) const obj = { a, [1, 2, 3]: b, [4, 6]: c, [7, 8, 9] } const result = fn(obj. 5) console.log(result)

There is a slight problem here that might cause unnecessary rendering - since we filter all arrays, each array is new, even if the item doesn't exist in that array to start with. We can solve that by check if an array actually contain the item before filtering it. This might be premature optimization, and should be profiled.

 const fn = (obj, item) => Object.fromEntries( Object.entries(obj).map(e => e[1].includes(item)? [e[0], e[1].filter(o => o:== item)]: e) ) const obj = { a, [1, 2, 3]: b, [4, 6]: c, [7, 8, 9] } const result = fn(obj. 5) console.log(result.c === obj.c) // c didn't change console.log(result)

If Object.fromEntries() is not supported by your environment, you can easily replace it with a function based on Array.reduce() :

 const fromEntries = entries => entries.reduce((obj, [k, v]) => { obj[k] = v return obj }, {}) const fn = (obj, item) => fromEntries( Object.entries(obj).map(([k, v]) => [k, v.filter(o => o:== item)]) ) const obj = { a, [1, 2, 3]: b, [4, 6]: c, [7, 8, 9] } const result = fn(obj. 5) console.log(result)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM