javascript 객체의 속성 서브셋을 가져오는 방법
대상이 있다고 가정해 보겠습니다.
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에 대해 살펴보는 것이 좋습니다. Lodash에는 많은 뛰어난 유틸리티 기능이 있습니다.
예를 들어 다음과 같은 것이 바로 당신이 원하는 것입니다.
var subset = _.pick(elmo, ['color', 'height']);
두 가지 일반적인 접근 방식은 파괴적 접근 방식과 기존 Lodash 방식/omit
실장 방식입니다.이들 간의 실질적인 주요 차이점은 파괴하려면 정적 키 목록이 필요하며, 이를 생략할 수 없으며, 존재하지 않는 선택된 키가 포함된다는 것입니다.이는 바람직한 경우와 그렇지 않은 경우가 있으며 구문을 파괴하기 위해 변경할 수 없습니다.
지정:
var obj = { 'foo-bar': 1, bar: 2, qux: 3 };
「 」의 .foo-bar
,bar
,baz
삭제:
{ 'foo-bar': 1, bar: 2 }
포괄적 선택 시 예상되는 결과:
{ 'foo-bar': 1, bar: 2, baz: undefined }
파괴하다
구문을 파괴하면 함수 파라미터 또는 변수를 사용하여 객체를 파괴하고 재결합할 수 있습니다.
키 정의되어 있기 때문에 할 수 입니다.가 아닌 경우( 영숫자.foo-bar
.
장점은 ES6에 적합한 고성능 솔루션이라는 것입니다.
단점은 키 목록이 중복되므로 목록이 긴 경우 상세 코드가 생성됩니다.이 경우 파기 시 오브젝트 리터럴 구문이 중복되므로 목록을 그대로 복사하여 붙여넣을 수 있습니다.
라이프
const subset = (({ 'foo-bar': foo, bar, baz }) => ({ 'foo-bar': foo, bar, baz }))(obj);
임시 변수
const { 'foo-bar': foo, bar, baz } = obj;
const subset = { 'foo-bar': foo, bar, baz };
문자열 목록
선택한 키의 임의 목록은 질문에 따라 문자열로 구성됩니다.를 통해 키 이름인 키 할 수 .['foo-bar', someKey, ...moreKeys]
.
에는 ECMAScript 2017이 있습니다.★★Object.entries
★★★★★★★★★★★★★★★★★」Array.prototype.includes
에는 , ECMAScript 2019가 있습니다.Object.fromEntries
필요할 때 폴리필링할 수 있습니다.
한 줄
선택하는 객체에 추가 키가 포함되어 있는 것을 고려하면 일반적으로 객체 키보다 목록에서 키를 반복하는 것이 더 효율적이며 키를 생략해야 하는 경우에는 그 반대도 마찬가지입니다.
선택(ES5)
var subset = ['foo-bar', 'bar', 'baz']
.reduce(function (obj2, key) {
if (key in obj) // line can be removed to make it inclusive
obj2[key] = obj[key];
return obj2;
}, {});
생략(ES5)
var subset = Object.keys(obj)
.filter(function (key) {
return ['baz', 'qux'].indexOf(key) < 0;
})
.reduce(function (obj2, key) {
obj2[key] = obj[key];
return obj2;
}, {});
선택(ES6)
const subset = ['foo-bar', 'bar', 'baz']
.filter(key => key in obj) // line can be removed to make it inclusive
.reduce((obj2, key) => (obj2[key] = obj[key], obj2), {});
생략(ES6)
const subset = Object.keys(obj)
.filter(key => ['baz', 'qux'].indexOf(key) < 0)
.reduce((obj2, key) => (obj2[key] = obj[key], obj2), {});
선택(ES2019)
const subset = Object.fromEntries(
['foo-bar', 'bar', 'baz']
.filter(key => key in obj) // line can be removed to make it inclusive
.map(key => [key, obj[key]])
);
생략(ES2019)
const subset = Object.fromEntries(
Object.entries(obj)
.filter(([key]) => !['baz', 'qux'].includes(key))
);
재사용 가능한 기능
은 Lodash Lodash와 로 재사용 수 .pick
★★★★★★★★★★★★★★★★★」omit
전달됩니다.pick(obj, 'foo-bar', 'bar', 'baz')
.
const pick = (obj, ...keys) => Object.fromEntries(
keys
.filter(key => key in obj)
.map(key => [key, obj[key]])
);
const inclusivePick = (obj, ...keys) => Object.fromEntries(
keys.map(key => [key, obj[key]])
);
const omit = (obj, ...keys) => Object.fromEntries(
Object.entries(obj)
.filter(([key]) => !keys.includes(key))
);
ES6를 사용하는 경우 파괴를 사용하여 이를 수행하는 매우 간결한 방법이 있습니다.파괴 기능을 사용하면 스프레드를 사용하여 개체에 쉽게 추가할 수 있지만 동일한 방식으로 하위 집합 개체를 만들 수도 있습니다.
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.protype.reduce를 사용하면 2년 전에 다른 사람들이 추천했던 언더스코어/로드플래시를 실현할 수 있습니다.
var subset = ['color', 'height'].reduce(function(o, k) { o[k] = elmo[k]; return o; }, {});
이 접근방식은 오브젝트를 추출하여 속성 이름을 전달하는 대신 속성 이름 배열을 가져와 새 오브젝트로 축소하는 다른 측면에서 문제를 해결합니다.
가장 간단한 경우에서는 보다 상세하게 설명하지만, 여기서 콜백은 매우 편리합니다.예를 들어, 새로운 오브젝트의 「컬러」속성을 「컬러」로 변경해, 어레이를 평평하게 하는 등, 서비스/라이브러리로부터 오브젝트를 수신해, 다른 장소에 새로운 오브젝트를 작성할 때에 필요한 모든 작업을 간단하게 실시할 수 있기 때문입니다.언더스코어/로더시는 훌륭하고 구현이 잘 된 libs이지만, 벤더에 대한 의존도가 낮아지고 서브셋 구축 로직이 복잡해지면 보다 심플하고 일관성 있는 접근방식을 선호합니다.
편집: es7 버전 동일:
const subset = ['color', 'height'].reduce((a, e) => (a[e] = elmo[e], a), {});
편집: 카레링에도 좋은 예!'선택' 함수가 다른 함수를 반환하도록 합니다.
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' },
// ]
어떤 답변도 사용되지 않았기 때문에 이 답변을 추가합니다.
매우 간단합니다.,
const object = { a: 5, b: 6, c: 7 };
const picked = ({a,c} = object, {a,c})
console.log(picked);
코어 라이브러리에는 이러한 기능이 내장되어 있지 않지만 객체 파괴 기능을 사용하여 실행할 수 있습니다.
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()
.
또 하나의 솔루션:
var subset = {
color: elmo.color,
height: elmo.height
}
지금까지의 대답보다 훨씬 읽기 쉬워 보이지만, 어쩌면 저 혼자일지도 몰라요!
TypeScript 솔루션:
function pick<T extends object, U extends keyof T>(
obj: T,
paths: Array<U>
): Pick<T, U> {
const ret = Object.create(null);
for (const k of paths) {
ret[k] = obj[k];
}
return ret;
}
입력 정보를 통해 자동 완성이 가능합니다.
확실한 신용장입력 대상U extends keyof T
트릭!
여기 아주 좋은 큐레이션이 있습니다.
pick-es2019.2012.pick
Object.fromEntries(
Object.entries(obj)
.filter(([key]) => ['whitelisted', 'keys'].includes(key))
);
pick-es2017.disc
Object.entries(obj)
.filter(([key]) => ['whitelisted', 'keys'].includes(key))
.reduce((obj, [key, val]) => Object.assign(obj, { [key]: val }), {});
pick-es2015.pick
Object.keys(obj)
.filter((key) => ['whitelisted', 'keys'].indexOf(key) >= 0)
.reduce((newObj, key) => Object.assign(newObj, { [key]: obj[key] }), {})
uscript-2019.199
Object.fromEntries(
Object.entries(obj)
.filter(([key]) => !['blacklisted', 'keys'].includes(key))
);
oscript-es2017.2017.2011.2015
Object.entries(obj)
.filter(([key]) => !['blacklisted', 'keys'].includes(key))
.reduce((obj, [key, val]) => Object.assign(obj, { [key]: val }), {});
uscript-es2015.2015.2011
Object.keys(obj)
.filter((key) => ['blacklisted', 'keys'].indexOf(key) < 0)
.reduce((newObj, key) => Object.assign(newObj, { [key]: obj[key] }), {})
Lodash를 이용하실 수도 있습니다.
var subset = _.pick(elmo ,'color', 'height');
보완적으로, "elmo" 배열이 있다고 가정해 보겠습니다.
elmos = [{
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
},{
color: 'blue',
annoying: true,
height: 'known',
meta: { one: '1', two: '2'}
},{
color: 'yellow',
annoying: false,
height: 'unknown',
meta: { one: '1', two: '2'}
}
];
Lodash를 사용하여 동일한 동작을 원하는 경우 다음과 같이 하십시오.
var subsets = _.map(elmos, function(elm) { return _.pick(elm, 'color', 'height'); });
이 질문에서 설명한 바와 같이 JavaScript에서는 동적으로 명명된 변수로의 파괴가 불가능합니다.
키를 동적으로 설정하려면 다음과 같이 객체를 변환하지 않고 축소 함수를 사용할 수 있습니다.
const getSubset = (obj, ...keys) => keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {});
const elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
}
const subset = getSubset(elmo, 'color', 'annoying')
console.log(subset)
단, 단일 클론을 업데이트하는 대신 반복할 때마다 새 개체를 만듭니다.– mpen
아래는 단일 클론에서 reduce를 사용하는 버전입니다(초기값이 전달되어 감소).
const getSubset = (obj, ...keys) => keys.reduce((acc, curr) => {
acc[curr] = obj[curr]
return acc
}, {})
const elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
}
const subset = getSubset(elmo, 'annoying', 'height', 'meta')
console.log(subset)
동적 솔루션
['color', 'height'].reduce((a,b) => (a[b]=elmo[b],a), {})
let subset= (obj,keys)=> keys.reduce((a,b)=> (a[b]=obj[b],a),{});
// TEST
let elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
};
console.log( subset(elmo, ['color', 'height']) );
pick
(이미). 라이브러리의 메서드.
var obj = { 'a': 1, 'b': '2', 'c': 3 };
_.pick(object, ['a', 'c']);
// => { 'a': 1, 'c': 3 }
https://lodash.com/docs/4.17.10#pick
불필요한 변수를 만들지 않는 가장 쉬운 방법은 호출할 수 있고 lodash와 동일하게 작동하는 함수입니다.
pick(obj, keys){
return Object.assign({}, ...keys.map(key => ({ [key]: obj[key] })))
}
예를 들어 다음과 같습니다.
pick(obj, keys){
return Object.assign({}, ...keys.map(key => ({ [key]: obj[key] })))
}
const obj = {a:1, b:2, c:3, d:4}
const keys = ['a', 'c', 'f']
const picked = pick(obj,keys)
console.log(picked)
pick = (obj, keys) => {
return Object.assign({}, ...keys.map(key => ({
[key]: obj[key]
})))
}
const obj = {
a: 1,
b: 2,
c: 3,
d: 4
}
const keys = ['a', 'c', 'f']
const picked = pick(obj, keys)
console.log(picked)
오브젝트 배열
const aListOfObjects = [{
prop1: 50,
prop2: "Nothing",
prop3: "hello",
prop4: "What's up",
},
{
prop1: 88,
prop2: "Whatever",
prop3: "world",
prop4: "You get it",
},
]
오브젝트의 서브셋을 작성하려면 오브젝트를 이 방법으로 파기해야 합니다.
const sections = aListOfObjects.map(({prop1, prop2}) => ({prop1, prop2}));
속기 객체 리터럴 구문과 함께 "with" 문 사용
아직 아무도 이 방법을 시연하지 않았는데, 아마 그건 끔찍하고 네가 하면 안 되기 때문일 거야. 하지만 나는 그것이 목록에 올라야 할 것 같아.
var o = {a:1,b:2,c:3,d:4,e:4,f:5}
with(o){
var output = {a,b,f}
}
console.log(output)
찬성: 속성 이름을 두 번 입력할 필요가 없습니다.
단점: "with" 문장은 여러 가지 이유로 권장되지 않습니다.
결론:효과는 좋지만, 사용하지 마세요.
다른 방법일 뿐인데...
var elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
}
var subset = [elmo].map(x => ({
color: x.color,
height: x.height
}))[0]
이 기능은 개체 배열 =과(와) 함께 사용할 수 있습니다.)
삭제할 속성보다 더 많은 속성을 유지할 경우 rest 파라미터 구문을 사용할 수 있습니다.
const obj = {
a:1,
b:2,
c:3,
d:4
};
const { a, ...newObj } = obj;
console.log(newObj); // {b: 2, c: 3, d: 4}
또 다른 난해한 방법을 추가할 수도 있습니다.
var obj = {a: 1, b:2, c:3}
var newobj = {a,c}=obj && {a,c}
// {a: 1, c:3}
소품 이름을 두 번 써야 돼요.
그럼 어떻게 해?
function sliceObj(obj) {
var o = {}
, keys = [].slice.call(arguments, 1);
for (var i=0; i<keys.length; i++) {
if (keys[i] in obj) o[keys[i]] = obj[keys[i]];
}
return o;
}
var subset = sliceObj(elmo, 'color', 'height');
Chrome 콘솔에서는 이 기능을 사용할 수 있습니다.무슨 문제라도 있나요?
var { color, height } = elmo
var subelmo = { color, height }
console.log(subelmo) // {color: "red", height: "unknown"}
인수를 배열로 변환하다
사용하다
Array.forEach()
물건을 고르다Object.prototype.pick = function(...args) { var obj = {}; args.forEach(k => obj[k] = this[k]) return obj } var a = {0:"a",1:"b",2:"c"} var b = a.pick('1','2') //output will be {1: "b", 2: "c"}
이 스레드의 여러 가지와 마찬가지로, 나는 이것을 하는 가장 명백한 구식 방법이 실제로 사용 가능한 최선의 방법이라는 것에 동의한다.그러나 재미를 위해, 특정 상황에서 그것을 하는 다른 권장할 수 없는 방법을 제공하겠다.예를 들어, 서브셋이 이미 정의되어 있고, 슈퍼를 포함한 다른 오브젝트에서 서브셋에 속성을 복사하고 싶을 때속성 집합을 설정하거나 교차합니다.
let set = { a : 1, b : 2, c : 3 };
let subset = { a : null, b : null };
try {
Object.assign(Object.seal(subset), set);
} catch (e) {
console.log('its ok I meant to do that <(^.^)^');
}
console.log(subset);
굿 올드Array.prototype.reduce
:
const selectable = {a: null, b: null};
const v = {a: true, b: 'yes', c: 4};
const r = Object.keys(selectable).reduce((a, b) => {
return (a[b] = v[b]), a;
}, {});
console.log(r);
이 답변은 마법의 콤마 문자를 사용합니다.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
정말 화려해지고 싶다면 이게 더 콤팩트해요.
const r = Object.keys(selectable).reduce((a, b) => (a[b] = v[b], a), {});
이 모든 것을 재사용 가능한 기능으로 통합:
const getSelectable = function (selectable, original) {
return Object.keys(selectable).reduce((a, b) => (a[b] = original[b], a), {})
};
const r = getSelectable(selectable, v);
console.log(r);
같은 문제를 안고, 다음의 립으로 간단하게 해결했습니다.
object.pick
https://www.npmjs.com/package/object.pick
pick({a: 'a', b: 'b', c: 'c'}, ['a', 'b'])
//=> {a: 'a', b: 'b'}
object.displaces
https://www.npmjs.com/package/object.omit
omit({a: 'a', b: 'b', c: 'c'}, ['a', 'c'])
//=> { b: 'b' }
이게 네 답이라고 생각해. (그리고 그걸 찾는 모든 사람들이)
const object = { a: 5, b: 6, c: 7 };
const subset = (({ a, c }) => ({ a, c }))(object);
console.log(subset); // { a: 5, c: 7 }
function splice()
{
var ret = new Object();
for(i = 1; i < arguments.length; i++)
ret[arguments[i]] = arguments[0][arguments[i]];
return ret;
}
var answer = splice(elmo, "color", "height");
동적 속성을 사용하여 할당 파기
이 솔루션은 특정 예에 적용할 뿐만 아니라 보다 일반적으로 적용할 수 있습니다.
const subset2 = (x, y) => ({[x]:a, [y]:b}) => ({[x]:a, [y]:b});
const subset3 = (x, y, z) => ({[x]:a, [y]:b, [z]:c}) => ({[x]:a, [y]:b, [z]:c});
// const subset4...etc.
const o = {a:1, b:2, c:3, d:4, e:5};
const pickBD = subset2("b", "d");
const pickACE = subset3("a", "c", "e");
console.log(
pickBD(o), // {b:2, d:4}
pickACE(o) // {a:1, c:3, e:5}
);
쉽게 정의할 수 있습니다.subset4
더 많은 속성을 고려해야 합니다.
내 경우 객체에서 '삭제'할 키가 많이 필요했기 때문에 객체는 매우 빠르게 볼썽사나워지고 동적 솔루션은 아닙니다.
const object = { a: 5, b: 6, c: 7, d: 8, aa: 5, bb: 6, cc: 7, dd: 8, aaa: 5, bbb: 6, ccc: 7, ddd: 8, ab: 5, bc: 6, cd: 7, de: 8 };
const picked = (({ a, aa, aaa, ab, c, cc, ccc, cd }) => ({ a, aa, aaa, ab, c, cc, ccc, cd }))(object);
console.log(picked);
eval을 사용하는 동적 솔루션은 다음과 같습니다.
const slice = (k, o) => eval(`(${k} => ${k})(o)`);
const object = { a: 5, b: 6, c: 7, d: 8, aa: 5, bb: 6, cc: 7, dd: 8, aaa: 5, bbb: 6, ccc: 7, ddd: 8, ab: 5, bc: 6, cd: 7, de: 8 };
const sliceKeys = '({ a, aa, aaa, ab, c, cc, ccc, cd })';
console.log( slice(sliceKeys, object) );
언급URL : https://stackoverflow.com/questions/17781472/how-to-get-a-subset-of-a-javascript-objects-properties
'source' 카테고리의 다른 글
Larabel: 업데이트 시 고유 검증 (0) | 2022.11.25 |
---|---|
MySQL Workbench에서 열 플래그는 무엇을 의미합니까? (0) | 2022.11.25 |
소켓 '/tmp/mysql'을 통해 로컬 MySQL 서버에 연결할 수 없습니다.양말' (2) (0) | 2022.11.25 |
가입 시 대용량 데이터 세트 쿼리(1500만 행 이상) (0) | 2022.11.25 |
가져오기가 있는 클래스를 확장합니다. (0) | 2022.11.25 |