जावास्क्रिप्ट ऑब्जेक्ट के गुणों का सबसेट कैसे प्राप्त करें


424

कहो कि मेरे पास एक वस्तु है:

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

मैं इसके गुणों के सबसेट के साथ एक नई वस्तु बनाना चाहता हूं।

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

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

मैं इसे कैसे प्राप्त कर सकता हूं?


2
अंडरस्कोर लाइब्रेरी में इस तरह के बहुत सारे सहायक कार्य हैं, इसे देखें: underscorejs.org/#pick
Stefan

4
मैंने सोचा कि emo.sliceपहली नज़र में कहा ।
बिल क्रिसवेल

1
दूसरे विचार पर ... मैं एक सबसेट नहीं बनाऊंगा ...
एंड्रयू

जवाबों:


673

वस्तु विनाशकारी और संपत्ति आशुलिपि का उपयोग करना

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

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


फिलिप Kewisch से:

यह वास्तव में सिर्फ एक अनाम फ़ंक्शन है जिसे तुरंत बुलाया जा रहा है। यह सब एमडीएन पर विनाशकारी असाइनमेंट पेज पर पाया जा सकता है । यहाँ एक विस्तारित रूप है

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)


37
आपको यह कैसे करना है के बारे में सीखा? कहीं भी किसी भी डॉक्स या लेख में मैंने नहीं देखा है (एमडीएन सहित) यह तीर के सिंटैक्स को ऑब्जेक्ट डिस्ट्रक्टिंग में इस्तेमाल किया जा रहा है। यह जानकर बहुत अच्छा लगा।
पापीरो

52
यह वास्तव में सिर्फ एक अनाम फ़ंक्शन है जिसे तुरंत बुलाया जा रहा है। यह सब एमडीएन पर विनाशकारी असाइनमेंट पेज पर पाया जा सकता है। यहाँ एक विस्तृत रूप दिया गया है: let unwrap = ({a, c}) => ({a, c}); let unwrap2 = function({a, c}) { return { a, c }; }; let picked = unwrap({ a: 5, b: 6, c: 7 });
फिलिप केव्यूस

8
वहाँ प्रसार ऑपरेटर के साथ गतिशील रूप से ऐसा करने का एक तरीका है?
टॉम सरदयू

4
@TomSarduy आप बाकी इस्तेमाल कर सकते हैं अगर आप जो दूर करने के लिए सहारा निर्दिष्ट करना चाहते हैं, उदाहरण के लिए const { b, ...picked } = objectपैदा करेगा pickedके रूप में { a: 5, c: 7 }। आपने केवल बी निकालने के लिए निर्दिष्ट किया है। हालाँकि, एक ऐसा संस्करण घोषित करने के लिए आपका एस्लिट आप पर नाराज़ होगा।
Qaribou

24
यहां एक नुकसान यह है कि आपको विशेषता नामों की श्रृंखला को दो बार पूरी तरह से टाइप करने की आवश्यकता है। यह उन मामलों में काफी मुद्दा हो सकता है जहां कई विशेषताओं को चुनने की आवश्यकता होती है।
गर्सहोम

144

मेरा सुझाव है कि लोदाश पर एक नज़र डालें ; इसमें बहुत सारे उपयोगी कार्य हैं।

उदाहरण के लिए pick()ठीक वही होगा जो आप चाहते हैं:

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

बेला


2
वही अंडरस्कोर के लिए। js
Dan

1
क्या चुनने के बजाय केवल कुछ क्षेत्रों को बाहर करने का कोई कार्य है? इसलिए मेरे पास लगभग 50 फ़ील्ड हैं, जो केवल 2 फ़ील्ड को छोड़कर सब कुछ चाहते हैं।
श्रीकांत प्रभु

7
हां! आप _.omit(elmo, ['voice'])सब कुछ वापस करने के लिए उपयोग कर सकते हैं लेकिनvoice
1

इस दृष्टिकोण के बारे में मुझे क्या पसंद नहीं है, आप फ़ील्ड नामों को उद्धरणों में डाल रहे हैं, इसलिए यह टाइपोस के लिए अतिसंवेदनशील है, आपके आईडीई में एक संपत्ति का नाम बदलने जैसे सामान्य रिफैक्टर्स इसे नहीं उठाएंगे, आदि।
एंडी

117

यदि आप ईएस 6 का उपयोग कर रहे हैं तो विनाशकारी का उपयोग करके ऐसा करने का एक बहुत ही संक्षिप्त तरीका है। विनाशकारी आपको स्प्रेड का उपयोग करके आसानी से वस्तुओं को जोड़ने की अनुमति देता है, लेकिन यह आपको उसी तरह से सबसेट ऑब्जेक्ट बनाने की अनुमति भी देता है।

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

6
यह केवल एक फ़ील्ड को हटाने के लिए काम करता है, न कि एक ज्ञात सबसेट का चयन करने के लिए? संभावित रूप से अज्ञात क्षेत्रों को हटाने के लिए अनंत संख्या है, लेकिन यह वही हो सकता है जो कुछ लोग तलाश कर रहे हैं
अलेक्जेंडर मिल्स

यह सच है, लेकिन यह कई ज्ञात क्षेत्रों को हटा सकता है जो तब किसी नई वस्तु को पुन: असाइन किया जा सकता है, इसलिए यह अभी भी इस प्रश्न के लिए प्रासंगिक लगता है। आगे वर्णन करने के लिए उत्तर में जोड़ा गया।
लॉरेन

1
यह मूल रूप से @ इवान नोसोव के उत्तर के रूप में जैसा है वैसा ही है , हालांकि यह यहां अधिक समझने योग्य तरीके से समझाया गया है
icc97

81

जबकि यह थोड़ा अधिक क्रियात्मक है, आप Array.prototyp.reduce का उपयोग करके 2 साल पहले अंडरस्कोर / लॉश की सिफारिश कर सकते हैं जो हर कोई कर सकता है

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

यह दृष्टिकोण इसे दूसरी तरफ से हल करता है: किसी वस्तु को लेने के बजाय उसे निकालने के लिए संपत्ति के नामों को पास करें, संपत्ति के नामों की एक सरणी लें और उन्हें एक नई वस्तु में कम करें।

हालांकि यह सरलतम मामले में अधिक क्रिया है, यहां एक कॉलबैक काफी आसान है, क्योंकि आप आसानी से कुछ सामान्य आवश्यकताओं को पूरा कर सकते हैं, जैसे नई वस्तु पर 'रंग' गुण को 'रंग' में बदलना, समतल सरणियां, आदि - किसी भी एक सेवा / पुस्तकालय से एक वस्तु प्राप्त करने और कहीं और आवश्यक एक नई वस्तु का निर्माण करते समय आपको जो चीजें करने की आवश्यकता होती है। हालांकि अंडरस्कोर / लॉश उत्कृष्ट, अच्छी तरह से लागू किए गए काम हैं, यह कम विक्रेता-निर्भरता के लिए मेरा पसंदीदा दृष्टिकोण है, और मेरे सबसेट-लॉजिक तर्क को और अधिक जटिल होने पर एक सरल, अधिक सुसंगत दृष्टिकोण।

संपादित करें: उसी का 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' },
// ]

3
es6 इसके लिए एरो फ़ंक्शंस के माध्यम से क्लीनर बनना संभव बनाता है, और Object.assign की वापसी (चूंकि किसी ऑब्जेक्ट को असाइन करने पर प्रॉपर्टी की वैल्यू लौटती है, लेकिन Object.assign ऑब्जेक्ट को लौटाता है।)
Qaribou

एक और es6 नोट: आप शायद ही कभी यह सब करने की जरूरत है, क्योंकि आप आम तौर पर सिर्फ विनाश कार्य या args। उदाहरण के function showToy({ color, height }) {लिए केवल वही होगा जो आपको दायरे में चाहिए। reduceजब आप क्रमबद्धता के लिए वस्तुओं को सरल बना रहे दृष्टिकोण मुख्य रूप से समझ में आता है।
जोशी ने Qaribou

6
वह ES6 संस्करण कम निष्पादन योग्य है, क्योंकि यह प्रत्येक पुनरावृत्ति के साथ सभी गुणों की एक प्रतिलिपि बनाता है। यह O (n ^ 2) में O (n) ऑपरेशन करता है। आपके पहले कोड ब्लॉक के बराबर एक ES6 होगाconst pick = (obj, props) => props.reduce((a, e) => (a[e] = obj[e], a), {});
4castle

@ 4castle yep अच्छी कॉल - कोई मतलब नहीं इतना परेशान। मुझे कॉमा सिंटैक्स पसंद है - रिटर्न का एक गुच्छा से बेहतर।
2048 में क़ारीबौ

1
@ शेवचेन्कोविकेटर मैं वास्तव में अपने मूल es6 संस्करण में उस दृष्टिकोण का उपयोग करता था, लेकिन @ 4castle की टिप्पणी के बाद इसे बदल दिया। मुझे लगता है कि प्रसार अधिक स्पष्ट है, लेकिन यह कोड में बड़ी वस्तुओं के लिए एक बड़ा अंतर है जो आसानी से एक अड़चन पर हो सकता है (जैसे कि रेंडरिंग डेटा को वापस करने में देरी fetchकर रहा है), इसलिए मैं कॉमा ऑपरेटर के उपयोग की व्याख्या करते हुए एक टिप्पणी जोड़ने की सलाह दूंगा।
Qaribou

45

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.entriesऔर Array.prototype.includes, ECMAScript 2019 में Object.fromEntries, जरूरत पड़ने पर उन्हें पॉलीफ़िल किया जा सकता है और कार्य को आसान बना सकता है:

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

एक-लाइनर को लाडश केpick समान सहायक कार्य के रूप में फिर से लिखा जा सकता है या 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 }

गुम चाबियों के बारे में एक नोट

विनाशकारी और पारंपरिक लोदाश जैसे 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 }

11
क्या शर्म की बात है कि यह जवाब इतना हाल ही में है और इस तरह यह एक्सपोजर नहीं मिल रहा है जो इसके हकदार हैं। IMO यह पूर्णता, सरलता, बहुमुखी प्रतिभा और, सिर्फ-कार्यशीलता के लिए स्वीकृत उत्तर होना चाहिए। मैं अपनी सबसे उपयोगी स्निपेट लाइब्रेरी में ES6 संस्करण रखूँगा।
वनअलबर्ट

ES5 - "अनट्रेडेड रेफ़रर्रर: ओब्ज परिभाषित नहीं है"
निखिल वर्तक

@ निखिलवर्तक यह उम्मीद है कि objचर वह चर है जो किसी वस्तु को संग्रहीत करता है। यदि आपका चर नाम अलग है, तो इसके बजाय इसका उपयोग करें obj
एस्टुस फ्लास्क

मेरी गलती! मैंने अनदेखा कर दिया Object.keys(obj)। स्लीपी।
निखिल वर्तक

34

कोर लाइब्रेरी में बिल्ट-इन जैसा कुछ नहीं है, लेकिन आप इसे करने के लिए ऑब्जेक्ट डिस्ट्रक्टिंग का उपयोग कर सकते हैं ...

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"]);

लोदश जैसे पुस्तकालय भी हैं _.pick()


1
महान, मुझे बस forEach को बदलना था: keys.forEach (key => {newObject [key] = sourceObject [key];});) कृपया, टिप्पणी को अद्यतन करें यदि यह समझ में आता है।
कांडन

34

मैं इस उत्तर को जोड़ रहा हूं क्योंकि उपयोग किए गए उत्तर में से कोई भी नहीं Comma operator

यह destructuring assignmentऔर ,ऑपरेटर के साथ बहुत आसान है

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

console.log(picked);

गतिशील गुण असाइनमेंट के लिए एक निश्चित वृद्धि के साथ यह इस तरह दिख सकता है:


2
मेरा बुरा, मुझे नहीं पता कि मैंने पहले क्या किया था कि यह काम नहीं करता था लेकिन यह काम करने लगता है
ekkis

1
यह सबसे अच्छा अभिव्यक्ति है, जब यह विनाशकारी हो जाता है
मोहम्मद अल्ल

1
यह समाधान चतुर है, लेकिन यह सख्त मोड (यानी, 'use strict') में काम नहीं करता है । मुझे ए ReferenceError: a is not defined
किंबौड़ी

8
ध्यान दें कि यह दृष्टिकोण दो चरों के साथ वर्तमान दायरे को प्रदूषित करता है aऔर c- संदर्भ के आधार पर स्थानीय या वैश्विक रूप से बेतरतीब ढंग से अधिलेखित न होने के लिए सावधान रहें। (स्वीकृत उत्तर एक इनलाइन फ़ंक्शन में दो स्थानीय चर का उपयोग करके इस समस्या से बचा जाता है, जो तत्काल निष्पादन के बाद दायरे से बाहर हो जाता है।)
mindplay.dk

2
नाम स्थान का प्रदूषण इसे पूरी तरह से अव्यावहारिक बनाता है। ऑब्जेक्ट गुण से मेल खाने वाले स्कोप में पहले से ही यह बहुत सामान्य है, यही कारण है कि प्रोप शॉर्टहैंड + डिस्ट्रक्ट्यूरिंग मौजूद है। बहुत अधिक संभावना है कि आपके पास मूल उदाहरण में पहले से ही परिभाषित ऊँचाई या रंग होगा।
Qaribou से जोश

23

एक और उपाय:

var subset = {
   color: elmo.color,
   height: elmo.height 
}

यह मुझे अभी तक किसी भी जवाब की तुलना में बहुत अधिक पठनीय लगता है, लेकिन शायद यह सिर्फ मेरे लिए है!


9
मैं फैंसी लेकिन भ्रमित कोड होने के कारण उत्पादक होना पसंद करता हूं, और वास्तविक जीवन सॉफ्टवेयर इंजीनियरिंग में यह सबसे पठनीय और बनाए रखने योग्य समाधान है।
Janos

1
हां, हालांकि, मेरे लिए, विनाशकारी और शॉर्टहैंड नोटेशन का उपयोग करने का एक उल्टा यह है कि यह कम त्रुटि वाला है। अगर मेरे पास हर बार के लिए एक पैसा होता है तो मैंने गलती से कॉपी और पेस्ट किए गए कोड को समाप्त कर दिया है subset = {color: elmo.color, height: elmo.color}, मुझे कम से कम एक ... ठीक है, एक पैसा भी चाहिए।
JHH

मैं विनाशकारी शॉर्टहैंड कम त्रुटि प्रवण नहीं कहूंगा क्योंकि यह
बजे

मुझे सहमत होना पड़ेगा। अवांछित चर के साथ संदर्भ को प्रदूषित किए बिना, यह अब तक का सबसे पठनीय समाधान है। बाकी देखने का तरीका भी भ्रामक है। मैं अपने कोड को समझना पसंद करता हूं दूसरा मैं इसे देखता हूं।
एंड्रयू

11

आप उपयोग कर सकते हैं लोदश का भी ।

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

लागू करते हुए, मान लें कि आपके पास "एल्मो" s की एक सरणी है:

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'}
    }
];

यदि आप एक ही व्यवहार चाहते हैं, तो लॉश का उपयोग करके, आप बस:

var subsets = _.map(elmos, function(elm) { return _.pick(elm, 'color', 'height'); });

10

गतिशील रूप से नामित चरों में Destructuring जावास्क्रिप्ट में असंभव के रूप में इस पर चर्चा की है सवाल

कुंजी को गतिशील रूप से सेट करने के लिए , आप निम्न प्रकार से वस्तु को म्यूट किए बिना फ़ंक्शन को कम कर सकते हैं:

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)

यह ध्यान रखना चाहिए कि आप प्रत्येक पुनरावृत्ति पर एक नया ऑब्जेक्ट बना रहे हैं, हालांकि एक क्लोन को अपडेट करने के बजाय। - एमपीएन

नीचे एकल क्लोन के साथ कम करने का उपयोग कर एक संस्करण है (कम करने के लिए पारित प्रारंभिक मूल्य को अपडेट करते हुए)।

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)


1
बहुत बढ़िया! यह मुझे समझ में नहीं आया कि कोष्ठक कितने महत्वपूर्ण हैं [c]:। मैं मान रहा हूं कि किसी तरह सी को संपत्ति के नाम के बजाय मूल्य के रूप में देखा जा रहा है। वैसे भी बहुत मस्त। +1
जॉन फेयरबैंक्स

धन्यवाद दोस्त! वह उपयोग एक चीज है जो मुझे जावास्क्रिप्ट के बारे में पसंद है, जो सामान्य कार्यों को बिना उपयोग के सक्षम बनाता है। बस, यह जो बनाता है वह आपको रनवे पर एक चर की कुंजी निर्धारित करता है। यदि आप var key = 'someKey' को परिभाषित करते हैं, तो आप इसे {[key]: 'value'} के रूप में उपयोग कर सकते हैं, जो आपको {someKey: 'value'} देता है। बहुत कूल।
मुहम्मट एंगिनर

1
यह ध्यान रखना चाहिए कि आप प्रत्येक पुनरावृत्ति पर एक नया ऑब्जेक्ट बना रहे हैं, हालांकि एक क्लोन को अपडेट करने के बजाय।
एमपीएन

1
@ अच्छा मिल गया। मैंने एकल क्लोन को जोड़ने वाला एक संस्करण जोड़ा है, जैसा कि आपने सुझाव दिया है कि चाबियों का एक समूह पास करने के बजाय आर्ग्स फैलाना है।
मुहम्मट एंगीनर

7

टाइपस्क्रिप्ट समाधान:

export function pick<T extends object, U extends keyof T>(obj: T, paths: Array<U>) {
    return paths.reduce((o, k) => {
        o[k] = obj[k];
        return o;
    }, Object.create(null));
}

टाइपिंग जानकारी यहां तक ​​कि ऑटो-पूर्ति के लिए भी अनुमति देता है:

को ऋण DefinitelyTyped के लिए U extends keyof Tचाल!


मेरे लिए काम नहीं कर रहा है।
नथिंग

@ निथिंग क्या आप वीएस कोड का उपयोग कर रहे हैं?
एमपीएन

हाँ, मैं VS कोड का उपयोग करता हूँ।
Nuthinking

@ निथकना और आपने उसे एक .ts फ़ाइल में डाल दिया है? वह काम करना चाहिए। मैंने इसे फिर से कोशिश की
एमपीएन


4

गतिशील समाधान

['color', 'height'].reduce((a,b) => (a[b]=elmo[b],a), {})


3

बस एक और तरीका ...

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]

आप इस फ़ंक्शन का उपयोग ऑब्जेक्ट्स की सरणी के साथ कर सकते हैं =)


2

कैसा रहेगा:

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');

यदि संपत्ति का मूल्य false(या झूठा) था, तो यह विफल हो जाएगा । jsfiddle.net/nfAs8
Alxandr

इसलिए मैंने इसे बदल दिया keys[i] in obj
एलक्लैनर्स

2

यह मेरे लिए क्रोम कंसोल में काम करता है। इसके साथ कोई समस्या?

var { color, height } = elmo
var subelmo = { color, height }
console.log(subelmo) // {color: "red", height: "unknown"}

4
यह अच्छा पढ़ता है, लेकिन दो अनावश्यक चर, रंग और ऊंचाई बनाता है।
user424174

आपकी टिप्पणी नहीं समझी। ओपी की आवश्यकता उन दो तत्वों वाले एक ऑब्जेक्ट को बनाने की थी
एमएसआई

@MSi यह केवल एक ऑब्जेक्ट नहीं बनाता है, यह दो चर भी बनाता है।
एड्रियन

1

गतिशील गुणों के साथ विनाशकारी असाइनमेंट

यह समाधान न केवल आपके विशिष्ट उदाहरण पर लागू होता है बल्कि अधिक सामान्यतः लागू होता है:

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अधिक गुणों को ध्यान में रखने के लिए आप आसानी से आदि को परिभाषित कर सकते हैं ।


1

अच्छा-बूढ़ा 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);

1
  1. तर्क को सरणी में बदलें

  2. 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"}

4
देशी प्रकार के प्रोटोटाइप का विस्तार करना बुरा व्यवहार माना जाता है, हालांकि यह काम करेगा। यदि आप लाइब्रेरी लिख रहे हैं तो ऐसा न करें।
एमिल बर्जरॉन

0
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");

0

प्रयत्न

const elmo={color:"red",annoying:!0,height:"unknown",meta:{one:"1",two:"2"}};

const {color, height} = elmo; newObject = ({color, height});

console.log(newObject); //{ color: 'red', height: 'unknown' }

0

इवान नोसोव जवाब में मेरे 2 सेंट जोड़ना :

मेरे मामले में मुझे वस्तु से बाहर 'कटा हुआ' होने के लिए कई कुंजियों की आवश्यकता थी इसलिए यह बहुत तेजी से बदसूरत हो रहा है और बहुत गतिशील समाधान नहीं है:

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);

तो यहाँ एक गतिशील समाधान का उपयोग किया गया है:

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) );

-2

नोट: हालांकि मूल प्रश्न पूछा गया था कि यह जावास्क्रिप्ट के लिए है, इसे नीचे समाधान द्वारा jQuery के रूप में किया जा सकता है

यदि आप यहाँ चाहते हैं तो आप एक स्लाइस के लिए नमूना कोड यहाँ jquery का विस्तार कर सकते हैं:

jQuery.extend({
  sliceMe: function(obj, str) {
      var returnJsonObj = null;
    $.each( obj, function(name, value){
        alert("name: "+name+", value: "+value);
        if(name==str){
            returnJsonObj = JSON.stringify("{"+name+":"+value+"}");
        }

    });
      return returnJsonObj;
  }
});

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


var temp = $.sliceMe(elmo,"color");
alert(JSON.stringify(temp));

यहाँ उसी के लिए पहेली है : http://jsfiddle.net/w633z/



1
@ChristianSchlensker यह जावास्क्रिप्ट है
केविन बी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.