[javascript] 불변으로 객체의 속성 제거

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

그러나 어떤 이유로 든 두 상태에서 속성을 삭제합니다.

내가 도와 줄 수 있습니까?



답변

파괴 할당 구문을 사용하는 것은 어떻 습니까?

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 } }


답변

내가 좋아하는 ES5 배열 방법을 찾아 filter, map그리고 reduce유용한 그들은 항상 새로운 배열이나 개체를 반환하기 때문이다. 이 경우 Object.keys객체를 반복하고 객체 Array#reduce로 다시 전환하는 데 사용합니다.

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


답변

lodash 라이브러리 _.omit(object, [paths])에서 사용할 수 있습니다

경로는 다음과 같이 중첩 될 수 있습니다. _.omit(object, ['key1.key2.key3'])


답변

ES6 객체 파괴 기능 만 사용하십시오.

const state = {
    c: {
       x: '42',
       y: '43'
    },
}

const { c: { y, ...c } } = state // generates a new 'c' without 'y'

console.log({...state, c }) // put the new c on a new state


답변

state.c다른 객체에 값을 복사하기 때문 입니다. 그리고 그 가치는 다른 자바 스크립트 객체에 대한 포인터입니다. 따라서 두 포인터 모두 동일한 객체를 가리 킵니다.

이 시도:

let newState = Object.assign({}, state);
console.log(newState == state); // false
console.log(newState.c == state.c); // true
newState.c = Object.assign({}, state.c);
console.log(newState.c == state.c); // now it is false
delete newState.c.y;

객체의 정밀 복사를 수행 할 수도 있습니다. 참조 이 질문에 당신은 당신을 위해 최선의 기능을 얻을 수 있습니다.


답변

이건 어때요:

function removeByKey (myObj, deleteKey) {
  return Object.keys(myObj)
    .filter(key => key !== deleteKey)
    .reduce((result, current) => {
      result[current] = myObj[current];
      return result;
  }, {});
}

삭제해야 할 키를 필터링 한 다음 나머지 키와 초기 객체에서 새 객체를 만듭니다. 아이디어는 Tyler McGinnes의 멋진 reactjs 프로그램에서 도난당했습니다.

JSBin


답변

function dissoc(key, obj) {
  let copy = Object.assign({}, obj)
  delete copy[key]
  return copy
}

또한 함수형 프로그래밍 툴킷을 찾고 있다면 Ramda를보십시오 .