从嵌套对象中删除数据而不改变
Remove data from nested objects without mutating
有什么优雅的方法可以从属于数组的数组中删除对象吗?
我已经使用 React 和 Redux 有一段时间了,但每次我必须在不改变状态的情况下删除或插入数据时都会卡住几个小时。
reducer 是一个数组,其中包含具有 ID 的对象和另一个包含对象的数组,如下所示:
[
{ id:123,
items:[
{ id: abc,
name: albert
},
...
]
},
...
]
我收到了两个 ID,需要删除 ID 为 abc
的项目。
您可以使用 Underscore's reject。它完全符合您的要求。
如果你决定使用普通 Javascript,我能想到的最优雅的方法是使用 Array.prototype.reduce
来减少状态:
var state = [
{ id: 123,
items:[
{ id: 'abc',
name: 'albert'
},
...
]
},
...
]
function filterOut (state) {
return (bucketId, personId) => {
return state.reduce((state, bucket) => {
return state.concat(
(bucketId === bucket.id) ?
Object.assign({}, bucket, {items: bucket.items.filter((person) => person.id !== personId)}) :
bucket
);
}, []);
}
}
var newState = filterOut(state)(123, 'abc');
通过 id 从数组中删除一个项目:
return state.filter(item => item.id !== action.id)
通过 id 从对象中删除键:
let copy = Object.assign({}, state) // assuming you use Object.assign() polyfill!
delete copy[action.id] // shallowly mutating a shallow copy is fine
return copy
(奖金)与 object spread operator proposal 相同:
let { [action.id]: deletedItem, ...rest } = state
return rest
您也可以使用lodash's omit method。
请注意,导入 lodash 会大大增加您的构建大小。通过仅导入特定方法来稍微控制它:
import omit from 'lodash/omit';
如果可能,我建议使用 中描述的对象展开运算符。
我这样解决了我的问题
if(action.type === "REMOVE_FROM_PLAYLIST"){
let copy = Object.assign({}, state)
delete copy.playlist[action.index].songs[action.indexSongs];
return copy;
}
希望对大家有所帮助。
const remove = (state, bucketId, personId) => state.map(
bucket => bucket.id === bucketId
? { ...bucket, items: bucket.items.filter(person => person.id !== personId) }
: bucket,
);
用法:
const state = [
{
id: 123,
items: [
{
id: 'abc',
name: 'Kinna',
},
{
id: 'def',
name: 'Meggy',
},
],
},
{
id: 456,
items: [
{
id: 'ghi',
name: 'Ade',
},
{
id: 'jkl',
name: 'Tades',
},
],
},
];
console.log(remove(state, 123, 'abc'));
有什么优雅的方法可以从属于数组的数组中删除对象吗? 我已经使用 React 和 Redux 有一段时间了,但每次我必须在不改变状态的情况下删除或插入数据时都会卡住几个小时。
reducer 是一个数组,其中包含具有 ID 的对象和另一个包含对象的数组,如下所示:
[
{ id:123,
items:[
{ id: abc,
name: albert
},
...
]
},
...
]
我收到了两个 ID,需要删除 ID 为 abc
的项目。
您可以使用 Underscore's reject。它完全符合您的要求。
如果你决定使用普通 Javascript,我能想到的最优雅的方法是使用 Array.prototype.reduce
来减少状态:
var state = [
{ id: 123,
items:[
{ id: 'abc',
name: 'albert'
},
...
]
},
...
]
function filterOut (state) {
return (bucketId, personId) => {
return state.reduce((state, bucket) => {
return state.concat(
(bucketId === bucket.id) ?
Object.assign({}, bucket, {items: bucket.items.filter((person) => person.id !== personId)}) :
bucket
);
}, []);
}
}
var newState = filterOut(state)(123, 'abc');
通过 id 从数组中删除一个项目:
return state.filter(item => item.id !== action.id)
通过 id 从对象中删除键:
let copy = Object.assign({}, state) // assuming you use Object.assign() polyfill!
delete copy[action.id] // shallowly mutating a shallow copy is fine
return copy
(奖金)与 object spread operator proposal 相同:
let { [action.id]: deletedItem, ...rest } = state
return rest
您也可以使用lodash's omit method。
请注意,导入 lodash 会大大增加您的构建大小。通过仅导入特定方法来稍微控制它:
import omit from 'lodash/omit';
如果可能,我建议使用
我这样解决了我的问题
if(action.type === "REMOVE_FROM_PLAYLIST"){
let copy = Object.assign({}, state)
delete copy.playlist[action.index].songs[action.indexSongs];
return copy;
}
希望对大家有所帮助。
const remove = (state, bucketId, personId) => state.map(
bucket => bucket.id === bucketId
? { ...bucket, items: bucket.items.filter(person => person.id !== personId) }
: bucket,
);
用法:
const state = [
{
id: 123,
items: [
{
id: 'abc',
name: 'Kinna',
},
{
id: 'def',
name: 'Meggy',
},
],
},
{
id: 456,
items: [
{
id: 'ghi',
name: 'Ade',
},
{
id: 'jkl',
name: 'Tades',
},
],
},
];
console.log(remove(state, 123, 'abc'));