[filter] ES6의 키로 객체 속성 필터링

객체가 있다고 가정 해 봅시다.

{
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
}

위의 객체를 필터링하여 다른 객체를 만들고 싶습니다.

 {
    item1: { key: 'sdfd', value:'sdfd' },
    item3: { key: 'sdfd', value:'sdfd' }
 }

Es6을 사용하여이를 수행하는 깨끗한 방법을 찾고 있으므로 스프레드 연산자를 사용할 수 있습니다.



답변

허용되는 값 목록이 있으면 다음을 사용하여 객체에 쉽게 유지할 수 있습니다.

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

const filtered = Object.keys(raw)
  .filter(key => allowed.includes(key))
  .reduce((obj, key) => {
    obj[key] = raw[key];
    return obj;
  }, {});

console.log(filtered);

이것은 다음을 사용합니다.

  1. Object.keysraw(원래 데이터)의 모든 속성을 나열한 다음
  2. Array.prototype.filter 다음을 사용하여 허용 된 목록에있는 키를 선택합니다.
    1. Array.prototype.includes 그들이 있는지 확인하기 위해
  3. Array.prototype.reduce 허용 된 속성만으로 새 객체를 작성합니다.

이렇게하면 허용 된 속성으로 얕은 복사본이 만들어 지지만 속성 자체는 복사되지 않습니다.

당신은 또한 사용할 수있는 개체의 확산 연산자를 그들에게 (덕분에 돌연변이없이 일련의 객체를 생성하는 이 언급 대한 rjerue을 ) :

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

const filtered = Object.keys(raw)
  .filter(key => allowed.includes(key))
  .reduce((obj, key) => {
    return {
      ...obj,
      [key]: raw[key]
    };
  }, {});

console.log(filtered);

퀴즈의 목적으로 원치 않는 필드를 원래 데이터에서 제거하려면 ( 추악한 돌연변이가 포함되어 있기 때문에 권장 하지 않습니다 ) includes검사를 다음과 같이 뒤집을 수 있습니다.

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

Object.keys(raw)
  .filter(key => !allowed.includes(key))
  .forEach(key => delete raw[key]);

console.log(raw);

돌연변이 기반 솔루션을 보여주기 위해이 예제를 포함하고 있지만 사용하지 않는 것이 좋습니다.


답변

ES6 구문을 사용해도 괜찮다면 여기여기에 언급 된 것처럼 가장 깨끗한 방법 은 다음 과 같습니다 .

const data = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const { item2, ...newData } = data;

이제 다음이 newData포함됩니다.

{
  item1: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

또는 키를 문자열로 저장 한 경우 :

const key = 'item2';
const { [key]: _, ...newData } = data;

후자의 경우 [key]로 변환 item2되지만 const할당을 사용하고 있으므로 할당의 이름을 지정해야합니다. _버림 값을 나타냅니다.

더 일반적으로:

const { item2, ...newData } = data; // Assign item2 to item2
const { item2: someVarName, ...newData } = data; // Assign item2 to someVarName
const { item2: _, ...newData } = data; // Assign item2 to _
const { ['item2']: _, ...newData } = data; // Convert string to key first, ...

이렇게하면 작업이 한 줄짜리로 줄어들뿐만 아니라 다른 키가 무엇인지 (보존하려는) 알 필요가 없습니다.


답변

가장 깨끗한 방법은 Lodash # pick을 사용하는 것입니다.

const _ = require('lodash');

const allowed = ['item1', 'item3'];

const obj = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
}

const filteredObj = _.pick(obj, allowed)


답변

이전에 언급되지 않은 것은 아니지만 일반적인 ES6 답변에 대한 답변을 결합하면됩니다.

const raw = {
  item1: { key: 'sdfd', value: 'sdfd' },
  item2: { key: 'sdfd', value: 'sdfd' },
  item3: { key: 'sdfd', value: 'sdfd' }
};

const filteredKeys = ['item1', 'item3'];

const filtered = filteredKeys
  .reduce((obj, key) => ({ ...obj, [key]: raw[key] }), {});

console.log(filtered);


답변

외부 라이브러리가없는 Modern JS의 한 줄에 있는 또 다른 솔루션 .

Destructuring “기능을 가지고 놀고있었습니다 :

const raw = {
    item1: { key: 'sdfd', value: 'sdfd' },
    item2: { key: 'sdfd', value: 'sdfd' },
    item3: { key: 'sdfd', value: 'sdfd' }
  };
var myNewRaw = (({ item1, item3}) => ({ item1, item3 }))(raw);
console.log(myNewRaw);


답변

이제 Object.fromEntries 메소드 를 사용하여 더 짧고 간단하게 만들 수 있습니다 (브라우저 지원 확인).

const raw = { item1: { prop:'1' }, item2: { prop:'2' }, item3: { prop:'3' } };

const allowed = ['item1', 'item3'];

const filtered = Object.fromEntries(
   Object.entries(raw).filter(
      ([key, val])=>allowed.includes(key)
   )
);

더 읽어보기 : Object.fromEntries


답변

generic을 추가하여 generic으로 ofilter구현할 oreduce수 있으므로 배열과 같은 방식으로 객체를 쉽게 필터링 할 수 있습니다.

const oreduce = (f, acc, o) =>
  Object
    .entries (o)
    .reduce
      ( (acc, [ k, v ]) => f (acc, v, k, o)
      , acc
      )

const ofilter = (f, o) =>
  oreduce
    ( (acc, v, k, o)=>
        f (v, k, o)
          ? Object.assign (acc, {[k]: v})
          : acc
    , {}
    , o
    )

여기서 작동하는 것을 볼 수 있습니다.

const data =
  { item1: { key: 'a', value: 1 }
  , item2: { key: 'b', value: 2 }
  , item3: { key: 'c', value: 3 }
  }

console.log
  ( ofilter
      ( (v, k) => k !== 'item2'
      , data
      )
      // [ { item1: { key: 'a', value: 1 } }
      // , { item3: { key: 'c', value: 3 } }
      // ]

  , ofilter
      ( x => x.value === 3
      , data
      )
      // [ { item3: { key: 'c', value: 3 } } ]
  )

아래의 브라우저에서 결과를 확인하십시오 –

이 두 기능은 여러 가지 방법으로 구현 될 수 있습니다. 나는 Array.prototype.reduce안쪽 에 붙이기로 선택 oreduce했지만 처음부터 쉽게 쓸 수 있습니다.