मैं एक कुंजी को छोड़कर किसी जावास्क्रिप्ट ऑब्जेक्ट को कैसे क्लोन कर सकता हूं?


307

मेरे पास एक सपाट जेएस वस्तु है:

{a: 1, b: 2, c: 3, ..., z:26}

मैं एक तत्व को छोड़कर ऑब्जेक्ट को क्लोन करना चाहता हूं:

{a: 1, c: 3, ..., z:26}

ऐसा करने का सबसे आसान तरीका क्या है (यदि संभव हो तो es6 / 7 का उपयोग करना पसंद करते हैं)?


मूल वस्तु को बदले बिना: JSON.parse (JSON.stringify ({... obj, 'key2': अपरिभाषित}))
infinity1975

जवाबों:


440

यदि आप Babel का उपयोग करते हैं तो आप x से गुणक b को चर b में कॉपी करने के लिए निम्नलिखित सिंटैक्स का उपयोग कर सकते हैं और फिर बाकी गुणों को चर y में कॉपी कर सकते हैं :

let x = {a: 1, b: 2, c: 3, z:26};
let {b, ...y} = x;

और इसमें ट्रांसप्लान्ट किया जाएगा:

"use strict";

function _objectWithoutProperties(obj, keys) {
  var target = {};
  for (var i in obj) {
    if (keys.indexOf(i) >= 0) continue;
    if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
    target[i] = obj[i];
  }
  return target;
}

var x = { a: 1, b: 2, c: 3, z: 26 };
var b = x.b;

var y = _objectWithoutProperties(x, ["b"]);

58
यदि आप अप्रयुक्त चर के लिए अपना कोड देते हैं, तो इसका परिणाम "अप्रयुक्त चर 'b' होगा।" हालांकि चेतावनी।
रॉस एलन

1
यदि आपके पास वाक्यविन्यास कैसा होगाlet x = [{a: 1, b: 2, c: 3, z:26}, {a: 5, b: 6, c: 7, z:455}];
ke3pup

14
@RossAllen एक विकल्प है ignoreRestSiblingsजिसे v3.15.0 (3 फरवरी, 2017) में जोड़ा गया था। देखें: प्रतिबद्ध c59a0ba
इल्या

4
@ इलियापकिन दिलचस्प। हालांकि यह थोड़ा आलसी लगता है क्योंकि यह इस तथ्य को नहीं बदलता है कि एक bगुंजाइश है।
रॉस एलन

2
यदि आपको मॉड्यूल बिल्ड विफल हो रहा है: SyntaxError: अप्रत्याशित टोकन, तो आपको संभवतः बैबल रेस्ट स्प्रेड ट्रांसफॉर्म प्लगइन को जोड़ना होगा। Babeljs.io/docs/plugins/transform-object-rest-spread
jsaven

133
var clone = Object.assign({}, {a: 1, b: 2, c: 3});
delete clone.b;

या यदि आप अपरिभाषित होने के लिए संपत्ति स्वीकार करते हैं:

var clone = Object.assign({}, {a: 1, b: 2, c: 3}, {b: undefined});

7
बस संपत्ति को हटाना एक स्पष्ट और सरल तरीका है।
जूल

24
हटाने के साथ चेतावनी यह है कि यह एक अपरिवर्तनीय संचालन नहीं है।
जावीद जमा

1
यह कुंजी रखता है
फरीद अलमृती

1
मेरी टिप्पणी उनके उत्तर को संपादित करने और हटाने के बयान को जोड़ने से पहले लिखी गई थी
फरीद अलनमौरी

यह वही है जो मैं देख रहा था, लेकिन थोड़ा और अलग तरीके से लागू किया गया: var cake = {... currentCake, requestorId: अपरिभाषित};
abelito

73

इल्या पालकिन के जवाब में जोड़ने के लिए: आप गतिशील रूप से चाबियाँ निकाल सकते हैं:

const x = {a: 1, b: 2, c: 3, z:26};

const objectWithoutKey = (object, key) => {
  const {[key]: deletedKey, ...otherKeys} = object;
  return otherKeys;
}

console.log(objectWithoutKey(x, 'b')); // {a: 1, c: 3, z:26}
console.log(x); // {a: 1, b: 2, c: 3, z:26};

बैबल REPL में डेमो

स्रोत:


3
यह एक अच्छा वाक्यविन्यास है।
हेनरिक

2
यह बहुत अच्छा है, लेकिन क्या अन-यूज्ड वर्जन डिलीट करने से बचने का कोई तरीका है? ऐसा नहीं है कि यह कोई समस्या पैदा कर रहा है, लेकिन JSHint को शिकायत करता है, और अजीब लगता है क्योंकि हम वास्तव में इसका उपयोग नहीं कर रहे हैं।
जॉनसन वोंग

6
@JohnsonWong का उपयोग कैसे करें _जिसके बारे में एक चर के लिए अनुमति दी जाती है जिसे आप उपयोग करने का इरादा नहीं रखते हैं?
रयान एच।

var b = {a:44, b:7, c:1}; let {['a']:z, ...others} = b; console.log(z , others ); // logs: 44, {b:7, c:1}
jimmont

70

जो लोग ES6 का उपयोग नहीं कर सकते हैं, उनके लिए आप उपयोग कर सकते हैं lodashया कर सकते हैं underscore

_.omit(x, 'b')

या ramda

R.omit('b', x)

6
नहीं इसे और अधिक उपयोग करने के लिए तार्किक होगा न आना यहाँ? _.omit(x, 'b')
टिब्लेट

साभार @tibalt इसके साथ उत्तर को अपडेट करें।
नोएल लवलेरस

हटाएं अधिक संक्षिप्त हैं - लॉश, अंडरस्कोर या रामा का उपयोग करना केवल उन परियोजनाओं के लिए प्रासंगिक है जो पहले से ही उपयोग करते हैं और उन्हें जानते हैं, अन्यथा यह 2018 और उसके बाद भी तेजी से अप्रासंगिक है।
23

1
@jimmont डिलीट पहले से ही अन्य उत्तरों में उल्लिखित है। डुप्लिकेट उत्तरों की कोई आवश्यकता नहीं है, आपको नहीं लगता? और निश्चित रूप से, यह केवल उन लोगों के लिए प्रासंगिक है जो पहले से ही लॉश या रमदा का उपयोग करते हैं। और यह केवल उन लोगों के लिए भी प्रासंगिक है जो ES5 के साथ चिपके हुए हैं और पहले इस उत्तर में कहा गया है।
नोएल लेवलेरेस

@dashmug मेरी पिछली टिप्पणी दृष्टिकोण की आलोचना थी (आपके उत्तर की नहीं) जो इस उत्तर में प्रस्तुत दृष्टिकोण का उपयोग करने के लिए चुनते समय ध्यान दिया जाना चाहिए। मुझे यह जानकारी चाहिए अगर मैं उत्तरों के माध्यम से पढ़ रहा था और मेरी टिप्पणी और उल्लेख करने का कारण है delete
जिम्मोंट

63

मैं इस ESNext एक लाइनर का उपयोग करें

const obj = { a: 1, b: 2, c: 3, d: 4 }
const clone = (({ b, c, ...o }) => o)(obj) // remove b and c
console.log(clone)


यदि आपको एक सामान्य उद्देश्य फ़ंक्शन की आवश्यकता है:

function omit(obj, props) {
  props = props instanceof Array ? props : [props]
  return eval(`(({${props.join(',')}, ...o}) => o)(obj)`)
}

// usage
const obj = { a: 1, b: 2, c: 3, d: 4 }
const clone = omit(obj, ['b', 'c'])
console.log(clone)


9
सरणी में लपेटने के बजाय और mapआप कर सकते हैं:(({b, c, ...others}) => ({...others}))(obj)
bucabay

@bucabay: शानदार! यह बहुत का सबसे अच्छा जवाब है! मानकों का अनुपालन, पूरी तरह से नोड आदि में काम करता है। आपको उत्तर के रूप में प्रस्तुत करना चाहिए।
david.pfx

3
शानदार जवाब दोस्त .. <3
अजितकुमार एस

5
@totymedli: मेरे द्वारा नहीं। मैं एक जादुई समारोह में, पठनीयता के आधार पर, सिंटैक्टिक रूप, मानक ES6 का हिस्सा ले लूंगा।
david.pfx

1
प्रतिभाशाली। बस इतना ही।
डार्कसॉल्सॉन्ग

22

आप इसके लिए एक सरल सहायक कार्य लिख सकते हैं। Lodash एक ही नाम के साथ एक समान कार्य है: न आना

function omit(obj, omitKey) {
  return Object.keys(obj).reduce((result, key) => {
    if(key !== omitKey) {
       result[key] = obj[key];
    }
    return result;
  }, {});
}

omit({a: 1, b: 2, c: 3}, 'c')  // {a: 1, b: 2}

इसके अलावा, ध्यान दें कि यह Object.assign से तेज है और तब हटाएं: http://jsperf.com/omit-key


11

शायद कुछ इस तरह:

var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;

क्या यह काफी अच्छा है? या cवास्तव में नकल नहीं हो सकती?


11

ऑब्जेक्ट डिस्ट्रक्टिंग का उपयोग करना

const omit = (prop, { [prop]: _, ...rest }) => rest;
const obj = { a: 1, b: 2, c: 3 };
const objWithoutA = omit('a', obj);
console.log(objWithoutA); // {b: 2, c: 3}


महान समाधान!
डेनिस मिखालेंको

2
मुझे लगता है कि यह समाधान JSLint में 'अप्रयुक्त चर' चेतावनी को रोकने के लिए है। दुर्भाग्य से, _ESLint के लिए इस मुद्दे को हल नहीं करता है ...
bert bynynooghe

6

जब आप किसी ऑब्जेक्ट को कॉपी करने का प्रयास कर रहे हों, तो किसी प्रॉपर्टी को हटाने की कोशिश करने पर हेरा फेरी लगती है। कहीं न कहीं आपको आदिम वेरिएबल्स को असाइन करना होता है इसलिए जावास्क्रिप्ट एक नया मूल्य बनाता है।

सरल चाल (भयावह हो सकती है) मैंने इसका इस्तेमाल किया था

var obj = {"key1":"value1","key2":"value2","key3":"value3"};

// assign it as a new variable for javascript to cache
var copy = JSON.stringify(obj);
// reconstitute as an object
copy = JSON.parse(copy);
// now you can safely run delete on the copy with completely new values
delete copy.key2

console.log(obj)
// output: {key1: "value1", key2: "value2", key3: "value3"}
console.log(copy)
// output: {key1: "value1", key3: "value3"}

मुझे वास्तव में यह पसंद है। कर सकता था JSON.parse(JSON.stringify(Object.assign({}, obj, { key2: undefined })));। इसे हटाना भी नहीं है, बस एक मिथ्या मूल्य चाहिए।
चाड

6

डायनामिक कुंजियों को छोड़ने का एक विकल्प यह है कि मेरा मानना ​​है कि अभी तक इसका उल्लेख नहीं किया गया है:

const obj = { 1: 1, 2: 2, 3: 3, 4: 4 };
const removeMe = 1;

const { [removeMe]: removedKey, ...newObj } = obj;

removeMeको removedKeyनजरअंदाज कर दिया जाता है। newObjबन जाता है { 2: 2, 3: 3, 4: 4 }। ध्यान दें कि हटाए गए कुंजी मौजूद नहीं है, मान अभी सेट नहीं किया गया था undefined


अच्छा समाधान है। मेरे पास एक समान उपयोग का मामला था (Reducer में गतिशील कुंजी)।
ericgio

4

सबसे आसान तरीका

const allAlphabets = {a: 1, b: 2, c: 3, ..., z:26};
const { b, ...allExceptOne } = allAlphabets;
console.log(allExceptOne);   // {a: 1, c: 3, ..., z:26}

3

Lodash न आना

let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}

हाँ, लोदश एक सुंदर विकल्प है, लेकिन मैं वैनिला ES6
andreasonny83

3

आप ऐसा करने के लिए प्रसार ऑपरेटर का उपयोग भी कर सकते हैं

const source = { a: 1, b: 2, c: 3, z: 26 }
const copy = { ...source, ...{ b: undefined } } // { a: 1, c: 3, z: 26 }

2
सुपर निफ्टी लगता है। यह हालांकि कुंजी को अपरिभाषित के रूप में रखता हैcopy
कानो

इसलिए आप अपरिभाषित कुंजियों को हटा सकते हैं यदि वहां केवल वही हों
विक्टर

1
सुनिश्चित नहीं है कि आपने कॉपी में अतिरिक्त प्रसार क्यों किया, const copy = { ...source, b: undefined } ठीक उसी तरह से उबलता है।
बर्ट ब्रिनोगे

3

संरचना का उपयोग करने के ऊपर दिए गए समाधान इस तथ्य से ग्रस्त हैं कि आपके पास एक उपयोग किया गया चर है, जो ईएसएलआईएन से शिकायत का कारण बन सकता है यदि आप इसका उपयोग कर रहे हैं।

तो यहाँ मेरे समाधान हैं:

const src = { a: 1, b: 2 }
const result = Object.keys(src)
  .reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})

अधिकांश प्लेटफार्मों पर (IE को छोड़कर बाबेल का उपयोग करते हुए), आप यह भी कर सकते हैं:

const src = { a: 1, b: 2 }
const result = Object.fromEntries(
  Object.entries(src).filter(k => k !== 'b'))


2

यदि आप एक विशाल चर के साथ काम कर रहे हैं, तो आप इसे कॉपी नहीं करना चाहते हैं और फिर इसे हटा सकते हैं, क्योंकि यह अक्षम होगा।

एक hasOwnProperty चेक के साथ एक साधारण लूप काम करना चाहिए, और यह भविष्य की जरूरतों के लिए अधिक अनुकूल है:

for(var key in someObject) {
        if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
                copyOfObject[key] = someObject[key];
        }
}

1
प्रसार ऑपरेटर समाधान ठीक से अच्छे सिंटैक्स के साथ ऐसा ही करता है।
david.pfx

2

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

const postData = {
   token: 'secret-token',
   publicKey: 'public is safe',
   somethingElse: true,
};

const a = {
   ...(({token, ...rest} = postData) => (rest))(),
}

/**
a: {
   publicKey: 'public is safe',
   somethingElse: true,
}
*/

2

मैंने इसे इस तरह से पूरा किया, मेरे Redux reducer के उदाहरण के रूप में:

 const clone = { ...state };
 delete clone[action.id];
 return clone;

दूसरे शब्दों में:

const clone = { ...originalObject } // note: original object is not altered
delete clone[unwantedKey]           // or use clone.unwantedKey or any other applicable syntax
return clone                        // the original object without the unwanted key

3 साल पहले के स्वीकृत उत्तर की तुलना में बहुत सारे अतिरिक्त काम लगते हैं (और दोनों विकल्प कई ब्राउज़रों के लिए ट्रांसपिलिंग पर निर्भर हैं)।
carpiediem

मेरे पास एक समान उपयोग मामला (reducer) है, इसलिए मैं एक अच्छा तरीका लेकर आया हूं जो म्यूटेशन के बिना डायनेमिक कुंजियों का समर्थन करता है। मूल रूप से: const { [removeMe]: removedKey, ...newObj } = obj;- इस सवाल पर मेरा जवाब देखें।
सोनाक्षी

1

मैंने हाल ही में इसे बहुत सरल तरीके से किया है:

const obj = {a: 1, b: 2, ..., z:26};

सिर्फ अवांछित संपत्ति को अलग करने के लिए प्रसार ऑपरेटर का उपयोग करना:

const {b, ...rest} = obj;

... और ऑब्जेक्ट। केवल 'शेष' भाग लेने के लिए असाइन करें:

const newObj = Object.assign({}, {...rest});

3
restपहले से ही एक नई वस्तु है- आपको अंतिम पंक्ति की आवश्यकता नहीं है। साथ ही, यह स्वीकृत समाधान के समान है।
carpiediem

0
const x = {obj1: 1, pass: 2, obj2: 3, obj3:26};

const objectWithoutKey = (object, key) => {
  const {[key]: deletedKey, ...otherKeys} = object;
  return otherKeys;
}

console.log(objectWithoutKey(x, 'pass'));

1
हालांकि यह कोड प्रश्न का हल प्रदान कर सकता है, इसलिए संदर्भ जोड़ना बेहतर है कि यह क्यों / कैसे काम करता है। यह भविष्य के उपयोगकर्ताओं को सीखने में मदद कर सकता है, और उस ज्ञान को अपने कोड में लागू कर सकता है। जब कोड समझाया जाता है, तो आपको उपयोगकर्ताओं से upvotes के रूप में सकारात्मक प्रतिक्रिया मिलने की संभावना होती है।
बोरवम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.