जावास्क्रिप्ट ES6 / ES5 सरणी और परिवर्तन में पाते हैं


133

मेरे पास वस्तुओं की एक सरणी है। मैं कुछ क्षेत्र से खोजना चाहता हूं, और फिर इसे बदलना चाहता हूं:

var item = {...}
var items = [{id:2}, {id:2}, {id:2}];

var foundItem = items.find(x => x.id == item.id);
foundItem = item;

मैं चाहता हूं कि यह मूल वस्तु को बदल दे। कैसे? (मुझे परवाह नहीं है कि यह भी दर्ज होगा)


खुराक आपकी नई वस्तु itemमें एक idकुंजी है? या क्या आपको लगता है कि आईडी के साथ ही itemऐरन एंट्री में ऑब्जेक्ट के सभी गुण हैं ?
कौशिक चटर्जी

जवाबों:


252

आप ऑब्जेक्ट के एरे में इंडेक्स को खोजने के लिए findIndex का उपयोग कर सकते हैं और इसे आवश्यकतानुसार बदल सकते हैं:

var item = {...}
var items = [{id:2}, {id:2}, {id:2}];

var foundIndex = items.findIndex(x => x.id == item.id);
items[foundIndex] = item;

यह विशिष्ट आईडी मानती है। यदि आपकी आईडी डुप्लिकेट है (आपके उदाहरण के अनुसार), तो यह संभव है कि आप फॉरएच का उपयोग करें।

items.forEach((element, index) => {
    if(element.id === item.id) {
        items[index] = item;
    }
});

16
@georg हालांकि, एक नई सरणी लौटाएगा।
कोडिंगइंट्रिग्यू

3
IE11 में => फ़ंक्शन काम नहीं करेगा। हाल ही में इस से काट लिया।
लुईस Cianci

1
हो सकता है इसका इस्तेमाल करने की बेहतर होगा letबजाय कीवर्डvar
Inus साहा

सिर्फ FYI करें, यह प्रेत के कुछ संस्करणों में काम नहीं करता है
सिड

1
मैं अधिक क्रिया विधि पसंद करता हूं @CodingIntrigue एक लाइनर का उपयोग करने के बजाय mapजो @georg उपयोग करता है। कम मानसिक जिम्नास्टिक यह पता लगाने के लिए आवश्यक है कि क्या हो रहा है। कोड की अतिरिक्त लाइन के लायक।
यहोशू पिंटर

44

मेरा सबसे अच्छा तरीका है:

var item = {...}
var items = [{id:2}, {id:2}, {id:2}];

items[items.findIndex(el => el.id === item.id)] = item;

FindIndex के लिए संदर्भ

और यदि आप नई वस्तु से प्रतिस्थापित नहीं करना चाहते हैं, तो इसके बजाय item, आप के क्षेत्रों की नकल कर सकते हैं Object.assign:

Object.assign(items[items.findIndex(el => el.id === item.id)], item)

एक विकल्प के रूप में .map():

Object.assign(items, items.map(el => el.id === item.id? item : el))

कार्यात्मक दृष्टिकोण :

सरणी को संशोधित न करें, एक नया प्रयोग करें, ताकि आप दुष्प्रभाव उत्पन्न न करें

const updatedItems = items.map(el => el.id === item.id ? item : el)

1
यदि मूल प्रश्न अंग्रेजी में था, तो कृपया एक अंग्रेजी पृष्ठ से लिंक करें। इसके अलावा, यह उदाहरण मानता है कि वस्तु हमेशा मिलती है।
raarts

1
आप इसे हमेशा एक कोशिश पकड़ अभिव्यक्ति में लपेट सकते हैं ... सही?
सोल्डप्लाटा साकेतोस

1
और पदों के प्रश्न के लिए पूरी तरह से शाब्दिक होने के नाते, वह एक तत्व को एक सरणी में संपादित करना चाहता है। वह जानना नहीं चाहता है कि यह मौजूद है या नहीं, इसलिए हम मानते हैं कि वह पहले भी ऐसा कर चुका है।
सोल्डप्लाटा साकेतोस

@SoldeplataSaketos हाँ, आप इसे एक में लपेट सकते हैंtry/catch , लेकिन आपको ऐसा नहीं करना चाहिए, क्योंकि तत्व का पता लगाना एक असाधारण मामला नहीं है; यह एक मानक मामला है जिसका आपको रिटर्न मूल्य की जाँच करके findIndexऔर उसके बाद केवल सरणी को अपडेट करना चाहिए जब तत्व पाया गया था।
वेन

20

एक अन्य दृष्टिकोण ब्याह का उपयोग करना है ।

splice()विधि को हटाने या मौजूदा तत्वों की जगह और / या नए तत्व जोड़कर एक सरणी की सामग्री को बदलता है जगह में

एनबी: यदि आप प्रतिक्रियाशील चौखटे के साथ काम कर रहे हैं, तो यह "व्यू", आपके एरे "" को अपडेट कर देगा।

उत्तर:

var item = {...}
var items = [{id:2}, {id:2}, {id:2}];

let foundIndex = items.findIndex(element => element.id === item.id)
items.splice(foundIndex, 1, item)

और मामले में आप केवल एक आइटम का एक मूल्य बदलना चाहते हैं, तो आप उपयोग कर सकते हैं खोज समारोह:

// Retrieve item and assign ref to updatedItem
let updatedItem = items.find((element) => { return element.id === item.id })

// Modify object property
updatedItem.aProp = ds.aProp

14

एक बदली हुई वस्तु और एक सरणी को देखते हुए:

const item = {...}
let items = [{id:2}, {id:3}, {id:4}];

सरणी पर पुनरावृत्ति करके नई वस्तु के साथ सरणी को अपडेट करें:

items = items.map(x => (x.id === item.id) ? item : x)

कृपया कोड पेस्ट न करें। समझाएँ कि क्या किया जा रहा है और यह कैसे हल करता है।
स्पेंसर

1
मुझे लगता है कि यह सबसे अच्छा समाधान है क्योंकि यह सबसे अच्छा प्रदर्शन है क्योंकि यह केवल एक बार सरणी पर जाता है और सरणी के संदर्भ को भी बदलता है, इसलिए यह परिवर्तनशील स्थितियों से बचाएगा
ओहद सदन

6

फ़िल्टर का उपयोग कर सकते हैं ।

const list = [{id:0}, {id:1}, {id:2}];
let listCopy = [...list];
let filteredDataSource = listCopy.filter((item) => {
       if (item.id === 1) {
           item.id = 12345;
        }

        return item;
    });
console.log(filteredDataSource);

ऐरे [ऑब्जेक्ट {आईडी: 0}, ऑब्जेक्ट {आईडी: 12345}, ऑब्जेक्ट {आईडी: 2}]


मुझे फ़िल्टर पसंद है क्योंकि यह एक नई सरणी बनाने की अनुमति देता है और इसके लिए भी मौजूद प्रविष्टियों को 'डिलीट' नहीं किया जाता है
pungggi

0

मेरे लिए काम किया

let returnPayments = [ ...this.payments ];

returnPayments[this.payments.findIndex(x => x.id == this.payment.id)] = this.payment;

1
कृपया कोड पेस्ट न करें। समझाएँ कि क्या किया जा रहा है और यह कैसे हल करता है।
एड्रियन मोल

स्वीकार किए गए अधिकांश उत्कीर्ण उत्तर बहुत अलग नहीं हैं, फिर भी आपने उन्हें उत्तर देने की दिशा में इंगित नहीं किया है .. ऐसा क्यों है?
ली एक्स

0

जबकि अधिकांश मौजूदा उत्तर महान हैं, मैं पाश के लिए एक पारंपरिक का उपयोग करके एक उत्तर शामिल करना चाहूंगा, जिसे यहां भी माना जाना चाहिए। ओपी एक जवाब का अनुरोध करता है जो ES5 / ES6 संगत है, और लूप के लिए पारंपरिक लागू होता है :)

इस परिदृश्य में सरणी फ़ंक्शंस का उपयोग करने में समस्या यह है कि वे ऑब्जेक्ट्स को म्यूट नहीं करते हैं, लेकिन इस मामले में, म्यूटेशन एक आवश्यकता है। लूप के लिए एक पारंपरिक का उपयोग करने का प्रदर्शन लाभ केवल (विशाल) बोनस है।

const findThis = 2;
const items = [{id:1, ...}, {id:2, ...}, {id:3, ...}];

for (let i = 0, l = items.length; i < l; ++i) {
  if (items[i].id === findThis) {
    items[i].iAmChanged = true;
    break;
  }
}

हालांकि मैं सरणी कार्यों का बहुत बड़ा प्रशंसक हूं, लेकिन उन्हें अपने टूलबॉक्स में एकमात्र उपकरण न बनने दें। यदि उद्देश्य सरणी को बदल रहा है, तो वे सबसे उपयुक्त नहीं हैं।


0

प्रसार ऑपरेटर का उपयोग कर एक-लाइनर।

 const updatedData = originalData.map(x => (x.id === id ? { ...x, updatedField: 1 } : x));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.