我想从对象内部的数组中删除一个元素,并用新值覆盖该对象。请参阅下面的示例。
var obj = {
a: [1, 2, 3],
b: [4, 5, 6],
c: [7, 8, 9]
}
我想在不知道元素在哪个数组中的情况下从obj
中删除数字5
我正在尝试使用上下文API更新react中的状态。它应该直接返回对象本身。
case ACTION: return {
...state,
obj: ?
}
预期最终结果:
var obj = {
a: [1, 2, 3],
b: [4, 6],
c: [7, 8, 9]
}
要生成具有更新值的新对象,可以使用Object.entries()
将对象转换为[key,value]的条目。映射条目,过滤值数组,然后用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)
这里有一个小问题,可能会导致不必要的渲染——因为我们过滤了所有数组,所以每个数组都是新的,即使该项一开始并不存在于该数组中。我们可以通过在筛选之前检查数组是否真的包含该项来解决这个问题。这可能是过早的优化,应该进行分析。
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)
如果您的环境不支持Object.fromEntries()
,您可以很容易地将其替换为基于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)
IMHO最简单的方法是splice
,该数组为:
obj.b.splice(1, 1);
编辑:
如果你不知道项目在哪里(根据注释(,你可以查看所有项目,并过滤每个数组:
const toRemove = 5;
Object.keys(obj).forEach(k => {
obj[k] = obj[k].filter(i => i != toRemove);
});