자바 스크립트 객체 속성의 하위 집합을 얻는 방법 {

객체가 있다고 가정 해보십시오.

elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
};

속성의 하위 집합으로 새 객체를 만들고 싶습니다.

 // pseudo code
 subset = elmo.slice('color', 'height')

 //=> { color: 'red', height: 'unknown' }

어떻게하면 되나요?



답변

객체 파괴 및 속성 속기 사용

const object = { a: 5, b: 6, c: 7  };
const picked = (({ a, c }) => ({ a, c }))(object);

console.log(picked); // { a: 5, c: 7 }

Philipp Kewisch에서 :

이것은 실제로 즉시 호출되는 익명 함수입니다. 이 모든 것은 MDN 의 Destructuring Assignment 페이지에서 찾을 수 있습니다 . 확장 된 형태는 다음과 같습니다

let unwrap = ({a, c}) => ({a, c});

let unwrap2 = function({a, c}) { return { a, c }; };

let picked = unwrap({ a: 5, b: 6, c: 7 });

let picked2 = unwrap2({a: 5, b: 6, c: 7})

console.log(picked)
console.log(picked2)

답변

Lodash를 살펴 보는 것이 좋습니다 . 많은 유용한 유틸리티 기능이 있습니다.

예를 들어 pick()원하는 것이 바로 다음과 같습니다.

var subset = _.pick(elmo, ['color', 'height']);

깡깡이


답변

ES6을 사용하는 경우에는 구조화를 사용하여이 작업을 수행하는 매우 간결한 방법이 있습니다. Destructuring을 사용하면 스프레드를 사용하여 객체를 쉽게 추가 할 수 있지만 동일한 방식으로 하위 세트 객체를 만들 수도 있습니다.

const object = {
  a: 'a',
  b: 'b',
  c: 'c',
  d: 'd',
}

// Remove "c" and "d" fields from original object:
const {c, d, ...partialObject} = object;
const subset = {c, d};

console.log(partialObject) // => { a: 'a', b: 'b'}
console.log(subset) // => { c: 'c', d: 'd'};

답변

좀 더 장황하지만 Array.prototype.reduce 를 사용하여 2 년 전 다른 사람들이 밑줄 / 로다시를 추천 한 것을 달성 할 수 있습니다 .

var subset = ['color', 'height'].reduce(function(o, k) { o[k] = elmo[k]; return o; }, {});

이 접근법은 반대편에서 그것을 해결합니다. 객체를 가져 와서 속성 이름을 전달하여 추출하고 속성 이름 배열을 가져 와서 새 객체로 줄이십시오.

가장 간단한 경우에 더 장황하지만, 여기의 콜백은 몇 가지 일반적인 요구 사항을 쉽게 충족시킬 수 있기 때문에 매우 편리합니다. 예를 들어 새 객체에서 ‘color’속성을 ‘color’로 변경하거나 배열을 평평하게하는 등 하나의 서비스 / 라이브러리에서 오브젝트를 수신하고 다른 곳에 필요한 새 오브젝트를 빌드 할 때 수행해야하는 작업. 밑줄 / 로대시는 우수하고 잘 구현 된 라이브러리이지만, 이것은 공급 업체 의존도를 낮추기 위해 선호하는 방법이며, 하위 집합 작성 논리가 복잡해지면 더 단순하고 일관된 방법입니다.

편집 : 같은 es7 버전 :

const subset = ['color', 'height'].reduce((a, e) => (a[e] = elmo[e], a), {});

편집 : 카레에 대한 좋은 예! ‘pick’함수가 다른 함수를 반환하도록합니다.

const pick = (...props) => o => props.reduce((a, e) => ({ ...a, [e]: o[e] }), {});

위의 방법은 다른 방법과 거의 비슷하지만 즉시 ‘피커’를 만들 수 있습니다. 예 :

pick('color', 'height')(elmo);

이 접근 방식에서 특히 좋은 점은 선택한 ‘선택’을 기능을 수행하는 모든 항목에 쉽게 전달할 수 있다는 것입니다 Array#map.

[elmo, grover, bigBird].map(pick('color', 'height'));
// [
//   { color: 'red', height: 'short' },
//   { color: 'blue', height: 'medium' },
//   { color: 'yellow', height: 'tall' },
// ]

답변

ES6 파괴

구조화 구문을 사용하면 함수 매개 변수 또는 변수를 사용하여 오브젝트를 구조화하고 재결합 할 수 있습니다.

제한 사항은 키 목록이 미리 정의되어 있으며 질문에서 언급했듯이 문자열로 나열 할 수 없다는 것입니다. 키가 영숫자가 아닌 경우 구조화가 더 복잡해집니다 (예 🙂 foo_bar.

단점은 키 목록을 복제해야하므로 목록이 긴 경우 자세한 코드가 생성된다는 것입니다. 이 경우에 구조를 제거하면 객체 리터럴 구문이 복제되므로 목록을 그대로 복사하여 붙여 넣을 수 있습니다.

단점은 ES6에 자연스러운 성능 솔루션이라는 것입니다.

IIFE

let subset = (({ foo, bar }) => ({ foo, bar }))(obj); // dupe ({ foo, bar })

임시 변수

let { foo, bar } = obj;
let subset = { foo, bar }; // dupe { foo, bar }

문자열 목록

선택된 키의 임의 목록은 질문에 따라 문자열로 구성됩니다. 이를 통해 사전 정의 할 수 없으며 키 이름이 포함 된 변수를 사용할 수 있습니다 pick(obj, 'foo', someKey, ...moreKeys).

각 JS 버전마다 하나의 라이너가 짧아집니다.

ES5

var subset = Object.keys(obj)
.filter(function (key) { 
  return ['foo', 'bar'].indexOf(key) >= 0;
})
.reduce(function (obj2, key) {
  obj2[key] = obj[key];
  return obj2;
}, {});

ES6

let subset = Object.keys(obj)
.filter(key => ['foo', 'bar'].indexOf(key) >= 0)
.reduce((obj2, key) => Object.assign(obj2, { [key]: obj[key] }), {});

또는 쉼표 연산자로 :

let subset = Object.keys(obj)
.filter(key => ['foo', 'bar'].indexOf(key) >= 0)
.reduce((obj2, key) => (obj2[key] = obj[key], obj2), {});

ES2019

ECMAScript를 2017가 Object.entriesArray.prototype.includesECMAScript를 2019가 있으며, Object.fromEntries필요하고 쉽게 작업을 할 때, 그들은 polyfilled 할 수 있습니다 :

let subset = Object.fromEntries(
  Object.entries(obj)
  .filter(([key]) => ['foo', 'bar'].includes(key))
)

하나의 라이너는 Lodashpick 와 유사 하거나 omit키 목록이 인수를 통해 전달 되는 도우미 함수로 다시 작성 될 수 있습니다 .

let pick = (obj, ...keys) => Object.fromEntries(
  Object.entries(obj)
  .filter(([key]) => keys.includes(key))
);

let subset = pick({ foo: 1, qux: 2 }, 'foo', 'bar'); // { foo: 1 }

누락 된 키에 대한 참고 사항

디스트 럭처링과 기존 Lodash와 유사한 pick기능 의 주요 차이점은 디스트 럭처링 에는 존재하지 않는 선택된 키가 undefined하위 집합에 값을 포함한다는 것입니다.

(({ foo, bar }) => ({ foo, bar }))({ foo: 1 }) // { foo: 1, bar: undefined }

이 동작은 바람직하거나 바람직하지 않을 수 있습니다. 구문을 파괴하기 위해 변경할 수 없습니다.

하지만 pick대신 집어 키의 목록을 반복하여 키 누락 포함하도록 변경 될 수있다 :

let inclusivePick = (obj, ...keys) => Object.fromEntries(
  keys.map(key => [key, obj[key]])
);

let subset = inclusivePick({ foo: 1, qux: 2 }, 'foo', 'bar'); // { foo: 1, bar: undefined }

답변

핵심 라이브러리에 내장 된 것과 같은 것은 없지만 객체 파괴를 사용하여 수행 할 수 있습니다 …

const {color, height} = sourceObject;
const newObject = {color, height};

유틸리티 함수를 작성할 수도 있습니다 …

const cloneAndPluck = function(sourceObject, keys) {
    const newObject = {};
    keys.forEach((obj, key) => { newObject[key] = sourceObject[key]; });
    return newObject;
};

const subset = cloneAndPluck(elmo, ["color", "height"]);

Lodash와 같은 라이브러리도 있습니다 _.pick().


답변

사용 된 답변이 없기 때문에이 답변을 추가하고 Comma operator있습니다.

그것은 매우 쉽게 destructuring assignment,연산자

const object = { a: 5, b: 6, c: 7  };
const picked = ({a,c} = object, {a,c})

console.log(picked);

동적 속성 할당이 향상되면 다음과 같이 보일 수 있습니다.