以不可变方式删除对象中的属性

2022-08-30 01:37:29

我正在使用Redux。在我的化简器中,我正在尝试从对象中删除属性,如下所示:

const state = {
    a: '1',
    b: '2',
    c: {
       x: '42',
       y: '43'
    },
}

我想要这样的东西,而不必改变原始状态:

const newState = {
    a: '1',
    b: '2',
    c: {
       x: '42',
    },
}

我试过了:

let newState = Object.assign({}, state);
delete newState.c.y

但由于某些原因,它会从这两个状态中删除该属性。

能帮我做到这一点吗?


答案 1

使用解构赋值语法怎么样?

const original = {
  foo: 'bar',
  stack: 'overflow',
};

// If the name of the property to remove is constant
const { stack, ...withoutFirst } = original;
console.log(withoutFirst); // Will be { "foo": "bar" }

// If the name of the property to remove is from a variable
const key = 'stack'
const { [key]: value, ...withoutSecond } = original;
console.log(withoutSecond); // Will be { "foo": "bar" }

// To do a deep removal with property names from variables
const deep = {
  foo: 'bar',
  c: {
   x: 1,
   y: 2
  }
};

const parentKey = 'c';
const childKey = 'y';
// Remove the 'c' element from original
const { [parentKey]: parentValue, ...noChild } = deep;
// Remove the 'y' from the 'c' element
const { [childKey]: removedValue, ...childWithout } = parentValue;
// Merge back together
const withoutThird = { ...noChild, [parentKey]: childWithout };
console.log(withoutThird); // Will be { "foo": "bar", "c": { "x": 1 } }

答案 2

我发现像 ES5 数组方法一样有用,因为它们总是返回新的数组或对象。在这种情况下,我将用于迭代对象,并将其变回对象。filtermapreduceObject.keysArray#reduce

return Object.assign({}, state, {
    c: Object.keys(state.c).reduce((result, key) => {
        if (key !== 'y') {
            result[key] = state.c[key];
        }
        return result;
    }, {})
});