जावास्क्रिप्ट में वस्तुओं की एक सरणी से अलग-अलग मान कैसे प्राप्त करें?


383

मुझे लगता है कि निम्नलिखित है:

var array = 
    [
        {"name":"Joe", "age":17}, 
        {"name":"Bob", "age":17}, 
        {"name":"Carl", "age": 35}
    ]

सभी अलग-अलग युगों की एक सरणी प्राप्त करने में सक्षम होने का सबसे अच्छा तरीका क्या है कि मुझे इसका परिणाम सरणी मिलें:

[17, 35]

क्या कोई तरीका है जो मैं वैकल्पिक रूप से डेटा या बेहतर तरीके से संरचना कर सकता हूं, जैसे कि मुझे "आयु" के मूल्य की जांच करने वाले प्रत्येक सरणी के माध्यम से पुनरावृति नहीं करनी होगी और इसके अस्तित्व के लिए किसी अन्य सरणी के खिलाफ जांच करनी चाहिए, और यदि नहीं, तो इसे जोड़ें?

अगर वहाँ कुछ तरीका मैं बस पुनरावृत्ति के बिना अलग उम्र खींच सकता था ...

वर्तमान अक्षम तरीके से मैं सुधार करना चाहूंगा ... अगर इसका मतलब है कि "सरणी" के बजाय वस्तुओं की एक सरणी है, लेकिन कुछ अद्वितीय कुंजी (यानी "1,2,3") के साथ वस्तुओं का एक "नक्शा" जो होगा ठीक भी है। Im सिर्फ सबसे अधिक कुशल तरीके की तलाश कर रहा हूं।

निम्नलिखित यह है कि मैं वर्तमान में इसे कैसे करता हूं, लेकिन मेरे लिए, यह कार्यकुशलता के लिए सिर्फ भयावह प्रतीत होता है, भले ही यह काम करता हो ...

var distinct = []
for (var i = 0; i < array.length; i++)
   if (array[i].age not in distinct)
      distinct.push(array[i].age)

34
पुनरावृत्ति "दक्षता के लिए गंभीर" नहीं है और आप "पुनरावृति के बिना" हर तत्व के लिए कुछ भी नहीं कर सकते हैं। आप विभिन्न कार्यात्मक दिखने वाले तरीकों का उपयोग कर सकते हैं, लेकिन आखिरकार, कुछ स्तर पर कुछ वस्तुओं पर चलना होगा।
Eevee

// 100% रनिंग कोड कॉन्स्टेंट लिस्टऑफटैग्स = [{आईडी: 1, लेबल: "हैलो", रंग: "रेड", सॉर्टिंग: 0}, {आईडी: 2, लेबल: "वर्ल्ड", कलर: "ग्रीन", सॉर्टिंग : 1}, {आईडी: 3, लेबल: "हैलो", रंग: "नीला", छँटाई: 4}, {आईडी: 4, लेबल: "धूप", रंग: "पीला", छँटाई: 5}, {आईडी : 5, लेबल: "हैलो", रंग: "लाल", छँटाई: 6}], कुंजियाँ = ['लेबल', 'रंग'], फ़िल्टर किया गया = listOfTags.filter (s => o => (k>) ? s.has (k) && s.add (k)) (कीसेमैप (k => o [k]); जॉइन ('।'))) (नया सेट); console.log (फ़िल्टर);
संदीप मिश्रा

1
इनाम बहुत अच्छा है, लेकिन दिए गए डेटा और जवाब के साथ सवाल पहले से ही यहां उत्तर दिया गया है: stackoverflow.com/questions/53542882/… । इनाम का उद्देश्य क्या है? क्या मुझे दो या अधिक कुंजियों के साथ इस विशेष समस्या का जवाब देना चाहिए?
नीना शोलेज़

Setऑब्जेक्ट और mapएस बेकार हैं। यह काम सिर्फ एक सरल .reduce()चरण है।
Redu

जवाबों:


126

यदि यह PHP होता तो मैं कुंजियों के साथ एक सरणी बनाता और array_keysअंत में लेता , लेकिन JS के पास ऐसी कोई लक्जरी नहीं है। इसके बजाय, यह प्रयास करें:

var flags = [], output = [], l = array.length, i;
for( i=0; i<l; i++) {
    if( flags[array[i].age]) continue;
    flags[array[i].age] = true;
    output.push(array[i].age);
}

15
नहीं, क्योंकि array_uniqueपूरे आइटम की तुलना करेंगे, न कि केवल उम्र के रूप में यहां पूछा गया है।
नीट द डार्क एबोल

6
मुझे लगता flags = {}है कि इससे अधिक बेहतर हैflags = []
zhuguowei

3
@zhuguowei शायद, हालांकि वहाँ विरल सरणियों के साथ वास्तव में कुछ भी गलत नहीं है - और मैंने यह भी माना कि ageअपेक्षाकृत छोटा पूर्णांक है (<120 निश्चित रूप से)
नीट द डार्क एबसोल

हम उन लोगों की कुल संख्या का पता कैसे लगा सकते हैं जिनकी उम्र समान है?
user1788736

605

यदि आप ES6 / ES2015 का उपयोग कर रहे हैं या बाद में आप इसे इस तरह से कर सकते हैं:

const unique = [...new Set(array.map(item => item.age))];

यहाँ यह कैसे करना है पर एक उदाहरण है।


11
मुझे एक त्रुटि मिलती है:TypeError: (intermediate value).slice is not a function
अंगजोब गितब जुब

7
@ थोमस ... का अर्थ है फैल ऑपरेटर। इस मामले में इसका मतलब है कि नया सेट बनाएं और इसे सूची में फैलाएं। आप इसके बारे में और अधिक जानकारी प्राप्त कर सकते हैं: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
व्लाद बेज्डन

10
टाइपस्क्रिप्ट के लिए आपको Array.from () में लिपटे नए सेट का उपयोग करना होगा ... मैं नीचे उस उत्तर को प्रदान करूंगा। @AngJobs
ईसाई मैथ्यू

4
क्या ऑब्जेक्ट में कई कुंजियों के आधार पर अद्वितीय वस्तुओं का पता लगाना संभव है?
जेफ्री सुजीत

13
यह समाधान @Russell Vea द्वारा कुछ महीने पहले लगभग शब्दशः दिया गया था । क्या आपने मौजूदा उत्तरों की जांच की? लेकिन फिर, 266+ वोट दिखाते हैं कि किसी और ने भी जाँच नहीं की।
डेन डैस्कलेस्क्यू

164

ES6 का उपयोग कर

let array = [
  { "name": "Joe", "age": 17 },
  { "name": "Bob", "age": 17 },
  { "name": "Carl", "age": 35 }
];
array.map(item => item.age)
  .filter((value, index, self) => self.indexOf(value) === index)

> [17, 35]

2
यदि मैं इसके सूचकांक के साथ मान प्राप्त करना चाहता हूं तो मैं कैसे उदाहरण प्राप्त कर सकता हूं: मैं {"नाम": "बॉब", "आयु": "17"}, {"नाम": "बॉब", "आयु" प्राप्त करना चाहता हूं। ":" 17 "}
अब्दुल्ला अल मामुन

10
इसलिए आपको स्क्रॉल करते रहना होगा
अलेजांद्रो बस्तीदास

5
@AbdullahAlMamun आप कॉल के बजाय .filter में मैप का उपयोग कर सकते हैं। सबसे पहले, इस तरह से करें:array.filter((value, index, self) => self.map(x => x.age).indexOf(value.age) == index)
Leo

1
पी एस:। पम के अंदर .फिल्टर धीमा हो सकता है, इसलिए बड़े सरणियों से सावधान रहें
लियो

2
@IvanNosov आपका स्निपेट बहुत अच्छा है, हालांकि यह व्याख्या की कई पंक्तियाँ हैं कि यह पॉइंटर्स के साथ मैप और फ़िल्टर डॉक्यूमेंटेशन के साथ कैसे काम करता है, यह शुरुआती के लिए एकदम सही और स्पष्ट कर
देगा

128

आप इस तरह एक शब्दकोश दृष्टिकोण का उपयोग कर सकते हैं। मूल रूप से आप उस मूल्य को निर्दिष्ट करते हैं जिसे आप "शब्दकोश" में एक कुंजी के रूप में अलग-अलग होना चाहते हैं (यहाँ हम शब्दकोश-मोड से बचने के लिए एक ऑब्जेक्ट के रूप में एक सरणी का उपयोग करते हैं)। यदि कुंजी मौजूद नहीं थी, तो आप उस मान को अलग से जोड़ते हैं।

यहाँ एक कार्यशील डेमो है:

var array = [{"name":"Joe", "age":17}, {"name":"Bob", "age":17}, {"name":"Carl", "age": 35}];
var unique = [];
var distinct = [];
for( let i = 0; i < array.length; i++ ){
  if( !unique[array[i].age]){
    distinct.push(array[i].age);
    unique[array[i].age] = 1;
  }
}
var d = document.getElementById("d");
d.innerHTML = "" + distinct;
<div id="d"></div>

यह O (n) होगा जहां n सरणी में वस्तुओं की संख्या है और m अद्वितीय मानों की संख्या है। O (n) से तेज़ कोई तरीका नहीं है क्योंकि आपको प्रत्येक मान का कम से कम एक बार निरीक्षण करना चाहिए।

इस के पिछले संस्करण में एक वस्तु का उपयोग किया गया था, और इसके लिए ये प्रकृति में मामूली थे, और तब से ऊपर मामूली रूप से अपडेट किए गए हैं। हालाँकि, मूल नमूने में दो संस्करणों के बीच प्रदर्शन में अग्रिम प्रतीत होने का कारण डेटा का नमूना आकार इतना छोटा होना था। इस प्रकार, पिछले संस्करण में मुख्य तुलना आंतरिक मानचित्र और फिल्टर मोड बनाम शब्दकोश मोड लुकअप के बीच अंतर को देख रही थी।

मैंने ऊपर दिए गए कोड को अपडेट किया है, जैसा कि मैंने उल्लेख किया है, हालांकि, मैंने 3. 3 के बजाय 1000 ऑब्जेक्ट के माध्यम से देखने के लिए jsperf को भी अपडेट किया है। इसमें कई प्रदर्शन नुकसान ( अप्रचलित jsperf ) शामिल हैं।

प्रदर्शन

https://jsperf.com/filter-vs-dEDIA-more-data जब मैंने यह शब्दकोश चलाया तो यह 96% तेज था।

फ़िल्टर बनाम शब्दकोश


4
तेजी से, और किसी भी अतिरिक्त प्लगइन्स की आवश्यकता के बिना। वास्तव में अच्छा
mihai

2
कैसे के बारे मेंif( typeof(unique[array[i].age]) == "undefined"){ distinct.push(array[i].age); unique[array[i].age] = 0; }
कालातीत

7
वाह प्रदर्शन नक्शा विकल्प के पक्ष में वास्तव में बदल गया है। उस jsperf लिंक पर क्लिक करें!
एटी

1
@ 98percentmonkey - वस्तु का उपयोग "शब्दकोश दृष्टिकोण" की सुविधा के लिए किया गया था। ऑब्जेक्ट के अंदर, ट्रैक की जाने वाली प्रत्येक घटना को एक कुंजी (या बिन) के रूप में जोड़ा जाता है। इस तरह, जब हम एक घटना के पार आते हैं, हम यह देखने के लिए देख सकते हैं कि क्या कुंजी (या बिन) मौजूद है; यदि यह मौजूद है, तो हम जानते हैं कि घटना अद्वितीय नहीं है - यदि यह मौजूद नहीं है, तो हम जानते हैं कि घटना अद्वितीय है और इसे इसमें जोड़ें
ट्रैविस जे

1
@ 98percentmonkey - किसी वस्तु का उपयोग करने का कारण यह है कि लुकअप O (1) है क्योंकि यह एक संपत्ति के नाम की एक बार जांच करता है, जबकि एक सरणी O (n) है क्योंकि इसे अस्तित्व की जांच करने के लिए प्रत्येक मूल्य को देखना होगा। प्रक्रिया के अंत में, ऑब्जेक्ट में कुंजियों (डिब्बे) का सेट अद्वितीय घटनाओं के सेट का प्रतिनिधित्व करता है।
ट्रैविस जे

90

यह है कि आप 25 अगस्त 2017 तक टाइपस्क्रिप्ट के लिए ES6 के माध्यम से नए सेट का उपयोग करके इसे कैसे हल करेंगे

Array.from(new Set(yourArray.map((item: any) => item.id)))

3
इससे मदद मिली, धन्यवाद से पहले। टाइप 'सेट' एक अरै टाइप प्रकार नहीं है
रोबर्ट किंग

1
यह एक बेहतरीन जवाब है। अनटाइल i ने इसे नीचे स्क्रॉल किया, मैं एक उत्तर लिखने जा रहा था: Object.keys (मान .reduce <any> (x, y) => {x [y] = null; वापसी x;}; {}} )); लेकिन यह उत्तर अधिक संक्षिप्त है और केवल तार के बजाय सभी डेटा प्रकारों पर लागू होता है।
जगुआर

1
यह जवाब शानदार है!
ल्यूकोकोड

78

ES6 सुविधाओं का उपयोग करके, आप कुछ ऐसा कर सकते हैं:

const uniqueAges = [...new Set( array.map(obj => obj.age)) ];

6
यह दृष्टिकोण केवल आदिम प्रकारों पर काम करेगा (जो कि यहाँ मामला है क्योंकि उम्र एक संख्या है) अभी तक वस्तुओं के लिए असफल होगी।
k0pernikus

किसी भी विचार यह कैसे दो कुंजी के साथ वस्तुओं के लिए काम करने के लिए?
सीगप्रकाश

1
कुछ इस तरहconst uniqueObjects = [ ...new Set( array.map( obj => obj.age) ) ].map( age=> { return array.find(obj => obj.age === age) } )
हार्ले बी

62

मैं सिर्फ मैप करूंगा और डंप हटाऊंगा:

var ages = array.map(function(obj) { return obj.age; });
ages = ages.filter(function(v,i) { return ages.indexOf(v) == i; });

console.log(ages); //=> [17, 35]

संपादित करें: Aight! प्रदर्शन के मामले में सबसे कुशल तरीका नहीं है, लेकिन सबसे सरल पठनीय आईएमओ है। यदि आप वास्तव में माइक्रो-ऑप्टिमाइज़ेशन की परवाह करते हैं या आपके पास भारी मात्रा में डेटा है तो एक नियमित forलूप अधिक "कुशल" होने वाला है।


3
@elclanrs - "सबसे अधिक कुशल प्रदर्शन तरीका" - यह दृष्टिकोण धीमा है
ट्रैविस जे

1
@ ईवे: मैं देख रहा हूं। आपके उत्तर में अंडरस्कोर संस्करण बहुत तेज नहीं है , मेरा मतलब है, अंत में आप चुनते हैं कि क्या अधिक सुविधाजनक है, मुझे संदेह है कि 1-30% अधिक या कम सामान्य परीक्षणों में "भारी सुधार" को दर्शाता है और जब ओपी / एस हजारों में होते हैं ।
एलक्लेन्स

4
तो यह बात पक्की। केवल तीन तत्वों के साथ , सबसे तेज़ चीज़ तीन चर बनाने और कुछ ifएस का उपयोग करना है । आपको तीन मिलियन के साथ कुछ बहुत अलग परिणाम मिलेंगे।
Eevee

1
तेजी से नहीं, लेकिन मेरे मामले में यह चाल चली क्योंकि मैं एक बड़े डेटासेट के साथ काम नहीं कर रहा हूं, धन्यवाद।
फेलिप ऐल्कॉन

37
var unique = array
    .map(p => p.age)
    .filter((age, index, arr) => arr.indexOf(age) == index)
    .sort(); // sorting is optional

// or in ES6

var unique = [...new Set(array.map(p => p.age))];

// or with lodash

var unique = _.uniq(_.map(array, 'age'));

ES6 का उदाहरण

const data = [
  { name: "Joe", age: 17}, 
  { name: "Bob", age: 17}, 
  { name: "Carl", age: 35}
];

const arr = data.map(p => p.age); // [17, 17, 35]
const s = new Set(arr); // {17, 35} a set removes duplications, but it's still a set
const unique = [...s]; // [17, 35] Use the spread operator to transform a set into an Array
// or use Array.from to transform a set into an array
const unique2 = Array.from(s); // [17, 35]

6
इस कोड को इस सवाल का जवाब कर सकते हैं, के बारे में अतिरिक्त संदर्भ प्रदान करने के लिए कैसे और क्यों यह हल करती है समस्या जवाब की दीर्घकालिक मूल्य में सुधार होगा।
अलेक्जेंडर

पहला जो इंडेक्सऑफ बनाम इंडेक्स का उपयोग कर रहा है वह सिर्फ शानदार है।
अफसोस

ध्यान दें कि यह केवल आदिम मूल्यों के लिए काम करता है। यदि आपके पास तारीखों की एक सरणी है, तो आपको कुछ और अनुकूलित तरीकों की आवश्यकता है। यहाँ और पढ़ें: codeburst.io/javascript-array-distinct-5edc93501dc4
मोलक्स

36

उन लोगों के लिए जो कुंजी द्वारा अद्वितीय सभी गुणों के साथ ऑब्जेक्ट वापस करना चाहते हैं

const array =
  [
    { "name": "Joe", "age": 17 },
    { "name": "Bob", "age": 17 },
    { "name": "Carl", "age": 35 }
  ]

const key = 'age';

const arrayUniqueByKey = [...new Map(array.map(item =>
  [item[key], item])).values()];

console.log(arrayUniqueByKey);

   /*OUTPUT
       [
        { "name": "Bob", "age": 17 },
        { "name": "Carl", "age": 35 }
       ]
   */

 // Note: this will pick the last duplicated item in the list.


2
नोट: यह सूची में अंतिम डुप्लिकेट आइटम उठाएगा।
यूजीन कुलबुहोव

1
इसको उत्तर में जोड़ना!
अरुण कुमार सैनी

1
ठीक वही जो मेरे द्वारा खोजा जा रहा था। साझा करने के लिए एक टन धन्यवाद!
१६:४६ में डेनेर

1
मुझे लगता है कि यह ईमानदार होने के लिए शीर्ष जवाब होना चाहिए!
जारोस्लाव बेन

26

कई वैध उत्तर पहले से ही हैं, लेकिन मैं एक को जोड़ना चाहता था जो केवल reduce()विधि का उपयोग करता है क्योंकि यह साफ और सरल है।

function uniqueBy(arr, prop){
  return arr.reduce((a, d) => {
    if (!a.includes(d[prop])) { a.push(d[prop]); }
    return a;
  }, []);
}

इसे इस तरह उपयोग करें:

var array = [
  {"name": "Joe", "age": 17}, 
  {"name": "Bob", "age": 17}, 
  {"name": "Carl", "age": 35}
];

var ages = uniqueBy(array, "age");
console.log(ages); // [17, 35]

20

forEach@ ट्रैविस-जे के उत्तर का संस्करण (आधुनिक ब्राउज़रों और नोड जेएस दुनिया पर उपयोगी):

var unique = {};
var distinct = [];
array.forEach(function (x) {
  if (!unique[x.age]) {
    distinct.push(x.age);
    unique[x.age] = true;
  }
});

क्रोम v29.0.1547 पर 34% तेज: http://jsperf.com/filter-versus-dEDIA/3

और एक सामान्य समाधान जो एक मैपर फ़ंक्शन लेता है (प्रत्यक्ष नक्शे की तुलना में धीमी है, लेकिन यह अपेक्षित है):

function uniqueBy(arr, fn) {
  var unique = {};
  var distinct = [];
  arr.forEach(function (x) {
    var key = fn(x);
    if (!unique[key]) {
      distinct.push(key);
      unique[key] = true;
    }
  });
  return distinct;
}

// usage
uniqueBy(array, function(x){return x.age;}); // outputs [17, 35]

1
मुझे जेनेरिक सॉल्यूशन सबसे अच्छा लगता है क्योंकि यह संभव नहीं है कि वास्तविक दुनिया के परिदृश्य में उम्र की एकमात्र विशिष्ट आवश्यकता हो।
-रियासत

5
जेनेरिक में, वास्तविक तत्वों की सूची वापस करने के लिए "dif.push (कुंजी)" को "dif.push (x)" में बदलें, जो मुझे अत्यधिक उपयोगी लगता है!
सिलस हेंसन

15

मैंने सभी नई परियोजनाओं में डिफ़ॉल्ट रूप से अंडरस्कोर चिपकाना शुरू कर दिया है , इसलिए मुझे कभी भी इन छोटी डेटा-मूंगिंग समस्याओं के बारे में सोचने की ज़रूरत नहीं है।

var array = [{"name":"Joe", "age":17}, {"name":"Bob", "age":17}, {"name":"Carl", "age": 35}];
console.log(_.chain(array).map(function(item) { return item.age }).uniq().value());

पैदा करता है [17, 35]


13

इसे हल करने का एक और तरीका यहां दिया गया है:

var result = {};
for(var i in array) {
    result[array[i].age] = null;
}
result = Object.keys(result);

मुझे नहीं पता कि यह समाधान दूसरों की तुलना में कितनी तेजी से है, लेकिन मुझे क्लीनर लुक पसंद है। ;-)


संपादित करें: ठीक है, ऊपर यहाँ सब का सबसे धीमा समाधान लगता है।

मैंने यहां एक प्रदर्शन परीक्षण मामला बनाया है: http://jsperf.com/distinct-values-from-array

उम्र (इंटेगर) के लिए परीक्षण के बजाय, मैंने नामों (स्ट्रिंग्स) की तुलना करने के लिए चुना।

विधि 1 (टीएस का समाधान) बहुत तेज है। दिलचस्प रूप से पर्याप्त है, विधि 7 अन्य सभी समाधानों को बेहतर बनाता है, यहां मैंने सिर्फ .indexOf () से छुटकारा पाया और "मैनुअल" कार्यान्वयन का उपयोग किया, लूप्ड फ़ंक्शन कॉलिंग से बचा:

var result = [];
loop1: for (var i = 0; i < array.length; i++) {
    var name = array[i].name;
    for (var i2 = 0; i2 < result.length; i2++) {
        if (result[i2] == name) {
            continue loop1;
        }
    }
    result.push(name);
}

सफारी और फ़ायरफ़ॉक्स का उपयोग करने के प्रदर्शन में अंतर आश्चर्यजनक है, और ऐसा लगता है जैसे क्रोम अनुकूलन पर सबसे अच्छा काम करता है।

मुझे बिल्कुल यकीन नहीं है कि दूसरों की तुलना में उपरोक्त स्निपेट्स इतनी जल्दी क्यों हैं, शायद किसी समझदार ने मेरे पास इसका जवाब दिया है। ;-)


9

का उपयोग कर lodash

var array = [
    { "name": "Joe", "age": 17 },
    { "name": "Bob", "age": 17 },
    { "name": "Carl", "age": 35 }
];
_.chain(array).pluck('age').unique().value();
> [17, 35]

2
क्या आप बता सकते हैं कि सादे जावास्क्रिप्ट के साथ ऐसा कैसे किया जाए जैसा कि प्रश्न में निहित है?
रस्किन

यह एक अंडरस्कोर फंक्शन _.chain
vini

2
लेकिन प्लक () लश में नहीं है।
यश वेकरिया

1
_.chain (सरणी) .map ( 'उम्र') अद्वितीय () मान ()।। मेरे लिए काम किया।
यश वेकरिया

संस्करण 4.0 में कुछ ब्रेकिंग परिवर्तन थे - stackoverflow.com/a/31740263/4050261
आदर्श मादरेचा




5

यहां एक बहुमुखी समाधान है जो कम उपयोग करता है, मानचित्रण की अनुमति देता है, और प्रविष्टि क्रम बनाए रखता है।

आइटम : एक सरणी

मैपर : एक यूनीरी फ़ंक्शन जो आइटम को मापदंड पर मैप करता है, या आइटम को मैप करने के लिए खाली है।

function distinct(items, mapper) {
    if (!mapper) mapper = (item)=>item;
    return items.map(mapper).reduce((acc, item) => {
        if (acc.indexOf(item) === -1) acc.push(item);
        return acc;
    }, []);
}

प्रयोग

const distinctLastNames = distinct(items, (item)=>item.lastName);
const distinctItems = distinct(items);

आप इसे अपने ऐरे प्रोटोटाइप में जोड़ सकते हैं और आइटम पैरामीटर को छोड़ सकते हैं यदि आपकी शैली ...

const distinctLastNames = items.distinct( (item)=>item.lastName) ) ;
const distinctItems = items.distinct() ;

आप मिलान को गति देने के लिए किसी ऐरे के बजाय सेट का भी उपयोग कर सकते हैं।

function distinct(items, mapper) {
    if (!mapper) mapper = (item)=>item;
    return items.map(mapper).reduce((acc, item) => {
        acc.add(item);
        return acc;
    }, new Set());
}

5

const x = [
  {"id":"93","name":"CVAM_NGP_KW"},
  {"id":"94","name":"CVAM_NGP_PB"},
  {"id":"93","name":"CVAM_NGP_KW"},
  {"id":"94","name":"CVAM_NGP_PB"}
].reduce(
  (accumulator, current) => accumulator.some(x => x.id === current.id)? accumulator: [...accumulator, current ], []
)

console.log(x)

/* output 
[ 
  { id: '93', name: 'CVAM_NGP_KW' },
  { id: '94', name: 'CVAM_NGP_PB' } 
]
*/


2
यह O (n ^ 2) की तरह दिखता है
Cepprakash

4

बस यह मिल गया और मुझे लगा कि यह उपयोगी है

_.map(_.indexBy(records, '_id'), function(obj){return obj})

अंडरस्कोर का उपयोग करते हुए , इसलिए यदि आपके पास इस तरह की कोई वस्तु है

var records = [{_id:1,name:'one', _id:2,name:'two', _id:1,name:'one'}]

यह आपको केवल अनोखी वस्तुएं देगा।

यहाँ क्या होता है कि indexByइस तरह से एक नक्शा देता है

{ 1:{_id:1,name:'one'}, 2:{_id:2,name:'two'} }

और सिर्फ इसलिए कि यह एक नक्शा है, सभी चाबियाँ अद्वितीय हैं।

तब मैं इस सूची को वापस सरणी के लिए मैप कर रहा हूं।

मामले में आपको केवल विशिष्ट मूल्यों की आवश्यकता है

_.map(_.indexBy(records, '_id'), function(obj,key){return key})

ध्यान रखें कि keyस्ट्रिंग के रूप में लौटा है इसलिए, यदि आपको इसके बजाय पूर्णांक की आवश्यकता है, तो आपको करना चाहिए

_.map(_.indexBy(records, '_id'), function(obj,key){return parseInt(key)})

4

मुझे लगता है कि आप groupBy फ़ंक्शन (Lodash का उपयोग करके) की तलाश कर रहे हैं

_personsList = [{"name":"Joe", "age":17}, 
                {"name":"Bob", "age":17}, 
                {"name":"Carl", "age": 35}];
_uniqAgeList = _.groupBy(_personsList,"age");
_uniqAges = Object.keys(_uniqAgeList);

परिणाम उत्पन्न करता है:

17,35

jsField डेमो: http://jsfiddle.net/4J2SX/201/


3

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

var array = 
[
    {"name":"Joe", "age":17}, 
    {"name":"Bob", "age":17}, 
    {"name":"Carl", "age": 35}
]
var uniqueAges = array.reduce((p,c,i,a) => {
    if(!p[0][c.age]) {
        p[1].push(p[0][c.age] = c.age);
    }
    if(i<a.length-1) {
        return p
    } else {
        return p[1]
    }
}, [{},[]])

इस परीक्षण के अनुसार मेरा समाधान प्रस्तावित उत्तर की तुलना में दोगुना है



3

मुझे पता है कि मेरा कोड थोड़ा लंबा और थोड़ा समय जटिलता है, लेकिन यह समझ में आता है इसलिए मैंने इस तरह की कोशिश की।

मैं यहां प्रोटोटाइप आधारित फ़ंक्शन विकसित करने की कोशिश कर रहा हूं और कोड भी बदलता है।

यहाँ, डिस्टिक्ट मेरा स्वयं का प्रोटोटाइप फ़ंक्शन है।

<script>
  var array = [{
      "name": "Joe",
      "age": 17
    },
    {
      "name": "Bob",
      "age": 17
    },
    {
      "name": "Carl",
      "age": 35
    }
  ]

  Array.prototype.Distinct = () => {
    var output = [];
    for (let i = 0; i < array.length; i++) {
      let flag = true;
      for (let j = 0; j < output.length; j++) {
        if (array[i].age == output[j]) {
          flag = false;
          break;
        }
      }
      if (flag)
        output.push(array[i].age);
    }
    return output;
  }
  //Distinct is my own function
  console.log(array.Distinct());
</script>


2

आप Array.prototype.includes है या करने के लिए तैयार हैं, तो polyfill यह, इस काम करता है:

var ages = []; array.forEach(function(x) { if (!ages.includes(x.age)) ages.push(x.age); });

1

मेरे नीचे दिए गए कोड में युगों की अनूठी सरणी के साथ-साथ नए सरणी में डुप्लिकेट आयु नहीं होगी

var data = [
  {"name": "Joe", "age": 17}, 
  {"name": "Bob", "age": 17}, 
  {"name": "Carl", "age": 35}
];

var unique = [];
var tempArr = [];
data.forEach((value, index) => {
    if (unique.indexOf(value.age) === -1) {
        unique.push(value.age);
    } else {
        tempArr.push(index);    
    }
});
tempArr.reverse();
tempArr.forEach(ele => {
    data.splice(ele, 1);
});
console.log('Unique Ages', unique);
console.log('Unique Array', data);```

1

मैंने टाइपस्क्रिप्ट में अपना खुद का लिखा, एक सामान्य मामले के लिए, जैसे कि कोटलिन में Array.distinctBy {}...

function distinctBy<T, U extends string | number>(array: T[], mapFn: (el: T) => U) {
  const uniqueKeys = new Set(array.map(mapFn));
  return array.filter((el) => uniqueKeys.has(mapFn(el)));
}

कहाँ Uहै, बेशक। ऑब्जेक्ट के लिए, आपको https://www.npmjs.com/package/es6-json-stable-stringify की आवश्यकता हो सकती है


1

मामले में आप पूरे ऑब्जेक्ट की अनूठी जरूरत है

const _ = require('lodash');

var objects = [
  { 'x': 1, 'y': 2 },
  { 'y': 1, 'x': 2 },
  { 'x': 2, 'y': 1 },
  { 'x': 1, 'y': 2 }
];

_.uniqWith(objects, _.isEqual);

[वस्तु {x: 1, y: 2}, वस्तु {x: 2, y: 1}]


downvoter: मन क्यों समझा रहा है?
सीगप्रकाश

1

इस पुराने प्रश्न का उत्तर देना बहुत व्यर्थ है, लेकिन एक सरल उत्तर है जो जावास्क्रिप्ट की प्रकृति के लिए बोलता है। जावास्क्रिप्ट में वस्तुएँ स्वाभाविक रूप से हैश टेबल हैं। हम इसका उपयोग अद्वितीय कुंजियों के हैश पाने के लिए कर सकते हैं:

var o = {}; array.map(function(v){ o[v.age] = 1; });

फिर हम हैश को अद्वितीय मानों की एक सरणी में कम कर सकते हैं:

var a2 = []; for (k in o){ a2.push(k); }

बस आपको जरूरत है। सरणी a2 में केवल अनन्य आयु होती है।


1

शानदार प्रदर्शन के साथ सरल वन-लाइनर। मेरे परीक्षणों में ईएस 6 समाधानों की तुलना में 6% तेज ।

var ages = array.map(function(o){return o.age}).filter(function(v,i,a) {
    return a.indexOf(v)===i
});

@ Jeb50 एक मल्टी-लाइन जोड़ने के लिए देखभाल जो पढ़ने में आसान है? यहाँ दूसरों को देखकर मुझे नहीं लगता कि उन्हें पढ़ना या समझना आसान है। मुझे लगता है कि इसे एक फ़ंक्शन में रखना सबसे अच्छा है जो बताता है कि यह क्या करता है।
क्रेग

2
तीर के कार्यों के साथ array.map( o => o.age).filter( (v,i,a) => a.indexOf(v)===i):। मैं फंक्शन कीवर्ड का उपयोग शायद ही कभी करता हूं कि मुझे दो बार चीजों को पढ़ना पड़ता है जब मैं इसे देखता हूं
ren
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.