ऑब्जेक्ट की सरणी में मान पर .join करें


273

यदि मेरे पास स्ट्रिंग्स की एक सरणी है, तो मैं .join()एक स्ट्रिंग प्राप्त करने के लिए विधि का उपयोग कर सकता हूं , प्रत्येक तत्व को अल्पविराम द्वारा अलग किया जा सकता है, जैसे:

["Joe", "Kevin", "Peter"].join(", ") // => "Joe, Kevin, Peter"

मेरे पास वस्तुओं की एक सरणी है, और मैं इसके भीतर आयोजित एक मूल्य पर एक समान संचालन करना चाहता हूं; इतने से

[
  {name: "Joe", age: 22},
  {name: "Kevin", age: 24},
  {name: "Peter", age: 21}
]

पहले की तरह ही आउटपुट प्राप्त करने के लिए, विशेषता joinपर विधि का प्रदर्शन करें name

वर्तमान में मेरे पास निम्नलिखित कार्य हैं:

function joinObj(a, attr){
  var out = [];

  for (var i = 0; i < a.length; i++){
    out.push(a[i][attr]);
  }

  return out.join(", ");
}

उस कोड के साथ कुछ भी गलत नहीं है, यह काम करता है, लेकिन अचानक मैं कोड की एक सरल, संक्षिप्त रेखा से बहुत अपूर्ण फ़ंक्शन में चला गया हूं। क्या यह लिखने का एक अधिक उपयुक्त, आदर्श रूप से अधिक कार्यात्मक तरीका है?


1
एक भाषा को एक उदाहरण के रूप में उपयोग करने के लिए, ऐसा करने का एक पैथोनिक तरीका होगा" ,".join([i.name for i in a])
जैकवेइडी

6
ES6 में आप ऐसा कर सकते हैं users.map(x => x.name).join(', ');:।
तोतली

जवाबों:


496

यदि आप वस्तुओं को किसी वस्तु में मैप करना चाहते हैं (इस मामले में एक संपत्ति)। मुझे लगता Array.prototype.mapहै कि यदि आप कार्यात्मक रूप से कोड करना चाहते हैं तो आप क्या देख रहे हैं।

[
  {name: "Joe", age: 22},
  {name: "Kevin", age: 24},
  {name: "Peter", age: 21}
].map(function(elem){
    return elem.name;
}).join(",");

आधुनिक जावास्क्रिप्ट में:

[
  {name: "Joe", age: 22},
  {name: "Kevin", age: 24},
  {name: "Peter", age: 21}
].map(e => e.name).join(",");

(बेला)

यदि आप पुराने ब्राउज़रों का समर्थन करना चाहते हैं, तो ईएस 5 अनुपालन नहीं हैं जो आप इसे हिला सकते हैं (ऊपर एमडीएन पृष्ठ पर एक पॉलीफिल है)। एक अन्य विकल्प अंडरस्कोरज की pluckविधि का उपयोग करना होगा :

var users = [
      {name: "Joe", age: 22},
      {name: "Kevin", age: 24},
      {name: "Peter", age: 21}
    ];
var result = _.pluck(users,'name').join(",")

1
यह वाला। हालाँकि, आपको IE <9 के लिए प्रोटोटाइप सदस्य को शिम करना होगा, यदि आपको इस रेट्रो-ब्राउज़र का समर्थन करने की आवश्यकता है।
टॉमी

@ टॉमी अच्छी टिप्पणी मैंने पॉलीफ़िल के बारे में स्पष्टीकरण के साथ-साथ अंडरस्कोर का उपयोग करके प्लक का उपयोग करने का सुझाव भी जोड़ा।
बेंजामिन ग्रुएनबाम

@jackweirdy मुझे खुशी है कि मैं मदद कर सकता हूं :) जो इसके लायक है उसके लिए, जैसे नक्शा / कम / फिल्टर 'पाइथोनिक' नहीं हैं और समझ में आने का दूसरा तरीका है। जावास्क्रिप्ट की नई प्रगति में प्रगति (सद्भाव) के साथ-साथ कुछ ब्राउज़र पहले से ही (फ़ायरफ़ॉक्स) आपके पास पायथोनिक समझ हैं। आप कर सकते हैं [x.name for x of users](कल्पना wiki.ecmascript.org/doku.php?id=harmony:array_comprehensions )। वर्थ का उल्लेख है कि जिस तरह मैप / कम / फिल्टर का उपयोग करना बहुत 'पाइथोनिक' नहीं है, दूसरा तरीका शायद जावास्क्रिप्ट में है। कॉफ़ीस्क्रिप्ट उनके साथ शांत है, हालांकि coffeescript.org
बेंजामिन ग्रुएनबाम

बस एक अद्यतन - सरणी समझ ईएस 6 से बाहर कर दी गई है, शायद हम उन्हें ईएस 7 में प्राप्त करेंगे।
बेंजामिन ग्रुएनबाम

कॉफ़ीस्क्रिप्ट में:users.map((obj) -> obj.name).join(', ')
केशा एंटोनोव

71

वैसे आप हमेशा toStringअपनी वस्तुओं की विधि को ओवरराइड कर सकते हैं:

var arr = [
    {name: "Joe", age: 22, toString: function(){return this.name;}},
    {name: "Kevin", age: 24, toString: function(){return this.name;}},
    {name: "Peter", age: 21, toString: function(){return this.name;}}
];

var result = arr.join(", ");
//result = "Joe, Kevin, Peter"

2
यह एक बहुत ही दिलचस्प दृष्टिकोण है, मुझे नहीं पता था कि आप जेएस में ऐसा कर सकते हैं। डेटा हालांकि एक एपीआई से आ रहा है, इसलिए यह शायद मेरे उपयोग के मामले के लिए उपयुक्त नहीं है, लेकिन यह निश्चित रूप से विचार के लिए भोजन है।
जैकवीर्डी

3
बहुत DRY नहीं लगता
BadHorsie

3
@BadHorsie नहीं, यह DRY नहीं है। लेकिन निश्चित रूप से आप सरणी के बाहर एक एकल फ़ंक्शन को परिभाषित कर सकते हैं और फिर फ़ोर toString-लूप का उपयोग करके इस फ़ंक्शन को सभी मदों की विधि को असाइन कर सकते हैं। या आप कंस्ट्रक्टर toStringके लिए prototypeसंपत्ति में एक विधि जोड़कर, निर्माण कार्यों से निपटने के दौरान इस दृष्टिकोण का उपयोग कर सकते हैं । यह उदाहरण हालांकि केवल मूल अवधारणा को दर्शाने वाला था।
तुलसीकुम

13

मैं भी reduceविधि का उपयोग कर आया हूँ , यह वही है जो ऐसा दिखता है:

[
  {name: "Joe", age: 22},
  {name: "Kevin", age: 24},
  {name: "Peter", age: 21}
].reduce(function (a, b) {return (a.name || a) + ", " + b.name})

(a.name || a)इसलिए पहला तत्व सही ढंग से इलाज किया जाता है, लेकिन बाकी (जहां है aएक स्ट्रिंग है, और इसलिए a.nameअपरिभाषित है) एक वस्तु के रूप में इलाज नहीं है।

संपादित करें: मैंने अब इसे इसके लिए फिर से सक्रिय कर दिया है:

x.reduce(function(a, b) {return a + ["", ", "][+!!a.length] + b.name;}, "");

जो मुझे लगता है कि क्लीनर aहमेशा की तरह एक स्ट्रिंग है, bहमेशा एक वस्तु है (के उपयोग के कारण) वैकल्पिक initialValue पैरामीटर में reduce)

6 महीने बाद संपादित करें: ओह मैं क्या सोच रहा था। "सफाई वाला"। मैंने कोड देवताओं को नाराज कर दिया है।


धन्यवाद: D के reduceरूप में व्यापक रूप से समर्थित नहीं है map(जो अजीब है, यह देखते हुए कि वे बहन की तरह हैं) इसलिए मैं अभी भी आपके उत्तर का उपयोग कर रहा हूं :)
jackweirdy

6 महीने बाद मेरे संपादन को देखते हुए, मैंने अब फैसला किया है कि मैं खुद को नौकरी पर नहीं रखूंगा ... यह चालाक है, लेकिन साफ ​​नहीं है।
जैकवीर्डी

9

मुझे नहीं पता कि बाहरी पुस्तकालय का उपयोग किए बिना इसे करने का एक आसान तरीका है, लेकिन मैं व्यक्तिगत रूप से अंडरस्कोर को पसंद करता हूं। जेएस जिसमें एरे, संग्रह आदि से निपटने के लिए उपयोगिताओं के टन हैं।

अंडरस्कोर के साथ आप कोड की एक पंक्ति के साथ यह आसानी से कर सकते हैं:

_.pluck(arr, 'name').join(', ')


मैंने पहले अंडरस्कोर को दबोच लिया है, मैं इसे एक तरह से देशी जेएस में करने की उम्मीद कर रहा था - यह एक बार पूरी विधि का उपयोग करने के लिए एक बार में एक सा खींचना है :)
jackweirdy

(कहां arrहै आपका सरणी, स्वाभाविक रूप से)
एड हिंचलिफ़

काफी उचित! मैं अपने आप को सभी जगह पर अंडरस्कोर का उपयोग कर पाता हूं इसलिए यह कोई मुद्दा नहीं है।
एड हिंचलिफ़


3

मान लें कि ऑब्जेक्ट सरणी चर द्वारा संदर्भित है users

यदि ES6 का उपयोग किया जा सकता है तो सबसे आसान समाधान होगा:

users.map(user => user.name).join(', ');

यदि नहीं, और लॉश का उपयोग किया जा सकता है:

 _.map(users, function(user) {
     return user.name;
 }).join(', ');

2

यदि ऑब्जेक्ट और डायनेमिक कुंजियाँ: "applications\":{\"1\":\"Element1\",\"2\":\"Element2\"}

Object.keys(myObject).map(function (key, index) {
    return myObject[key]
}).join(', ')

0

एक पुराना धागा जिसे मैं जानता हूं, लेकिन फिर भी इस पर आने वाले किसी भी व्यक्ति के लिए प्रासंगिक है।

Array.map यहाँ सुझाया गया है जो एक बहुत ही बढ़िया तरीका है जिसका मैं हर समय उपयोग करता हूँ। Array.reduce का भी उल्लेख किया गया था ...

मैं व्यक्तिगत रूप से इस उपयोग के मामले के लिए एक Array.reduce का उपयोग करूंगा। क्यों? कोड थोड़ा कम / साफ होने के बावजूद। यह मैप फंक्शन को पाइप से जुड़ने की तुलना में बहुत अधिक कुशल है।

इसका कारण यह है क्योंकि सरणी में ऑब्जेक्ट के सभी नामों के साथ एक नया सरणी वापस करने के लिए Array.map को प्रत्येक तत्व पर लूप करना पड़ता है। Array.join तब शामिल होने के लिए सरणी की सामग्री पर लूप करता है।

आप एक ही लाइन पर कोड प्राप्त करने के लिए टेम्पलेट शाब्दिक का उपयोग करके जवाब को कम करने वाले jackweirdys की पठनीयता में सुधार कर सकते हैं। "सभी आधुनिक ब्राउज़रों में भी समर्थित"

// a one line answer to this question using modern JavaScript
x.reduce((a, b) => `${a.name || a}, ${b.name}`);

0

यकीन नहीं हो रहा है, लेकिन यह सब जवाब देता है कि वे काम करते हैं, लेकिन ऑप्टोमियल नहीं हैं क्योंकि दो स्कैन कर रहे हैं और आप इसे एक ही स्कैन में कर सकते हैं। भले ही O (2n) को O (n) माना जाता है, लेकिन हमेशा सही O (n) होना बेहतर होता है।

const Join = (arr, separator, prop) => {
    let combined = '';
    for (var i = 0; i < arr.length; i++) {
        combined = `${combined}${arr[i][prop]}`;
        if (i + 1 < arr.length)
            combined = `${combined}${separator} `;
    }
    return combined;
}

यह पुराने स्कूल की तरह लग सकता है, लेकिन मुझे इस तरह से करने की अनुमति देता है:

skuCombined = Join(option.SKUs, ',', 'SkuNum');

-1

इसे इस्तेमाल करे

var x= [
  {name: "Joe", age: 22},
  {name: "Kevin", age: 24},
  {name: "Peter", age: 21}
]

function joinObj(a, attr) {
  var out = []; 
  for (var i=0; i<a.length; i++) {  
    out.push(a[i][attr]); 
  } 
 return out.join(", ");
}

var z = joinObj(x,'name');
z > "Joe, Kevin, Peter"
var y = joinObj(x,'age');
y > "22, 24, 21"

2
यह प्रश्न में फ़ंक्शन के समान है, कम बहुमुखी को छोड़कर, क्योंकि आपने nameविशेषता को हार्ड-कोड किया है। ( आपके फ़ंक्शन के तर्क का उपयोग नहींa[i].name करता है, यह इसके बराबर है ।)namea[i]['name']
nnnnnn
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.