डुप्लिकेट निकालें एक सरणी बनाते हैं


100

मेरे पास वस्तुओं का एक समूह है जो इस तरह दिखता है:

var array = [
    {id:123, value:"value1", name:"Name1"},
    {id:124, value:"value2", name:"Name1"},
    {id:125, value:"value3", name:"Name2"},
    {id:126, value:"value4", name:"Name2"}
    ...
];

जैसा कि आप देख सकते हैं, कुछ नाम दोहराए जाते हैं। मैं केवल नामों के साथ एक नया सरणी प्राप्त करना चाहता हूं, लेकिन अगर कोई नाम दोहराता है तो मैं इसे फिर से जोड़ना नहीं चाहता। मुझे यह सरणी चाहिए:

var newArray = ["Name1", "Name2"];

मैं इसके साथ करने की कोशिश कर रहा हूं map:

var newArray = array.map((a) => {
    return a.name;
});

लेकिन समस्या यह है कि यह रिटर्न:

newArray = ["Name1", "Name1", "Name2", "Name2"];

मैं अंदर कुछ स्थिति कैसे सेट कर सकता हूं map, इसलिए यह पहले से मौजूद एक तत्व को वापस नहीं करेगा। मैं mapकुछ अन्य ECMAScript 5 या ECMAScript 6 सुविधा के साथ ऐसा करना चाहता हूं ।


2
फिर सरणी से डुप्लिकेट निकालें।
तुषार

5
कैसे के बारे में Set? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
14


आईडी युक्त रेखा क्यों: 125 अल्पविराम के साथ समाप्त नहीं होती है?
पीटर मोर्टेंसन

कृपया ध्यान दें कि .indexOf () का उपयोग करने वाले सभी उत्तरों को खराब प्रदर्शन होगा यदि सरणी बड़ी है, उनकी द्विघात जटिलता के कारण । मैं ईएस 6 सेट का उपयोग करने या एक शब्दकोश के रूप में ईएस 5 ऑब्जेक्ट का उपयोग करने की सलाह दूंगा
joeytwiddle

जवाबों:


210

ES6 के साथ, आप Setकेवल वस्तुओं के नाम मैप करने के बाद, अद्वितीय मूल्यों के लिए उपयोग कर सकते हैं ।

यह प्रस्ताव आइटम को एक नए सरणी में एकत्रित करने के लिए एक फैल सिंटैक्स... का उपयोग करता है ।

const array = [{ id: 123, value: "value1", name:"Name1" }, { id: 124, value: "value2", name: "Name1" }, { id: 125, value: "value3", name: "Name2" }, { id: 126, value: "value4", name: "Name2" }],
      names = [...new Set(array.map(a => a.name))];

console.log(names);


9
मेरी जानकारी के लिए .. क्या करता ...है?
राजशेखर रेड्डी

9
@RajshekarReddy, यह एक पुनरावृत्त वस्तु के साथ एक सरणी के निर्माण के लिए एक फैला हुआ वाक्यविन्यास है...
नीना शोल्ज़

5
मैं "सेट" के लिए खुद को नहीं बढ़ा रहा हूं, बल्कि प्रसार ऑपरेटर के चतुर उपयोग के लिए। कुछ नया सीखना या व्यावहारिक उदाहरण के लिए लागू कुछ नया देखना हमेशा अच्छा होता है, इसलिए यह पोस्ट एक उत्थान के योग्य है।
14

33
यह सिर्फ मेरी निजी राय है, बल्कि एक आम है । का उपयोग Array.fromरूपांतरण के इरादे को बेहतर बनाता है (और यह भी समझना आसान है / newbies के लिए खोज), प्रसार सिंटैक्स का उपयोग केवल उसी स्थान पर किया जाना चाहिए जहां फैला हुआ तत्व कई में से एक है। शायद इसे "बुरा व्यवहार" कहना थोड़ा कठोर है, क्षमा करें, मुझे उम्मीद है कि इसे एक सामान्य मुहावरा बनने से रोका जा सकेगा।
बरगी

3
@KRyan ES6 इतना नया है? 2015 के जून में इसे अंतिम रूप दिया गया है। नई सुविधाओं को समझना और उपयोग करना शुरू करने का समय आ गया है
edc65

64

यदि आप एक जावास्क्रिप्ट समाधान की तलाश कर रहे हैं जो ES 6 (कोई सेट नहीं) है तो आप ऐरे की reduceविधि का उपयोग कर सकते हैं :

var array=[
  {id:123, value:"value1", name:"Name1"},
  {id:124, value:"value2", name:"Name1"},
  {id:125, value:"value3", name:"Name2"},
  {id:126, value:"value4", name:"Name2"}
];
var names = array.reduce(function (a, b) {
  if (a.indexOf(b.name) == -1) {
    a.push(b.name)
  }
  return a;
}, []);

console.log(names);


2
इस उत्तर का यह भी लाभ है कि इसमें मध्यवर्ती सरणियों या सेटों की आवश्यकता नहीं होती है, विशेष रूप से केवल स्वयं के नाम वाले वाले। (यह वस्तुओं के सरणी से सीधे वस्तुओं के सरणी में जाता है।) +1
jpmc26

@Iestestledabearonce, क्या यह दूसरा परम वस्तु नहीं है जैसा कि लौटाया गया है?
काइदो

हाँ, लेकिन यह एक तरह से दूसरे से सीधे नहीं जाता है जैसे कि छांटना या फ़िल्टर, एक खाली सरणी से इसका पुनर्निर्माण।
मैंने एक बार एक भालू को कुश्ती दी।

1
@ डीकेल - छोटा संस्करण :)var names = array.reduce(function(a, b) { a.indexOf(b.name) === -1 && a.push(b.name) return a; }, []);
रेयॉन

3
@ रेयान कृपया स्रोत कोड के आकार पर बहुत अधिक ध्यान न दें, यह कई स्व-निर्मित प्रोग्रामर के लिए एक सामान्य नुकसान है, सबसे महत्वपूर्ण बात, आपका कार्यक्रम कुशल और पठनीय होना चाहिए।
पत्ती

16

व्यक्तिगत रूप से मैं यह नहीं देखता कि क्यों हर कोई ES 6 के साथ सभी फैंसी हो रहा है। यदि यह मेरा कोड होता तो मैं यथासंभव कई ब्राउज़रों का समर्थन करना पसंद करता।

var array=[
{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"},
{id:126, value:"value4", name:"Name2"}
];

   // Create array of unique names
var a = (function(a){
  for (var i = array.length; i--;)
    if (a.indexOf(array[i].name) < 0) a.push(array[i].name);
  return a;
})([]);

console.log(a);


2
क्या indexOfहर समय -ing के बजाय एक शब्दकोष के रूप में एक वस्तु का उपयोग करना अधिक प्रदर्शनकारी नहीं होगा ? जैसे added[name] = trueऔर if(added[name])इसके बजाय if(a.indexOf(name))
बोजिदर मारिनोव

7
"व्यक्तिगत रूप से मैं यह नहीं देखता कि हर कोई es6 के साथ सभी फैंसी क्यों प्राप्त कर रहा है" आप क्यों आ रहे हैं goto fail, अपने सूचकांक चर को एन्कोडिंग दायरे में लीक कर रहे हैं , आदि आदि ईएस 6 अच्छे कारणों के लिए मानक में कोडित किया गया था, और सबसे अधिक के लिए है पुराने ब्राउज़रों के लिए पॉलीफ़िल / ट्रांसफ़ॉर्म को आंशिक रूप से आसान बनाना।
जारेद स्मिथ

5
अधिक पठनीय? यह एक सरणी पर आइटम धक्का है कि पाश के लिए एक पागल है। इससे ज्यादा पढ़ने योग्य नहीं है ......
मैंने एक बार एक भालू को कुश्ती दी थी।

4
काफी ईमानदारी से यह सिर्फ लगता है जैसे आप के बारे में शिकायत करने के लिए कुछ खोजने के लिए बहुत मुश्किल तरह से कोशिश कर रहे हैं।
मैंने एक बार एक भालू को कुश्ती दी।

2
"मैं प्रसिद्ध ऐप्पल एसएसएल बग का उल्लेख कर रहा हूं" - यह इतना प्रसिद्ध नहीं है कि आप बस इसे संदर्भ से बाहर यादृच्छिक टिप्पणियों में संदर्भित कर सकते हैं और लोगों से इसे पहचानने की उम्मीद कर सकते हैं।
हज्जाजमन

14

तुम भी बस के mapसाथ गठबंधन कर सकते हैंfilter

var array = [
  {id:123, value:"value1", name:"Name1"},
  {id:124, value:"value2", name:"Name1"},
  {id:125, value:"value3", name:"Name2"},
  {id:126, value:"value4", name:"Name2"}
];

var unique = array
  .map( item => item.name )
  .filter( ( item, idx, arr ) => arr.indexOf( item ) == idx ) 

console.log(unique)


11

आप उपयोग कर सकते हैं Object.keys () पुनरावृत्ति की वस्तु परिणाम से एक दिया वस्तु की अपनी गणनीय संपत्ति नामों की सरणी प्राप्त करने arrayके साथ चर Array.prototype.reduce () जहां चाबियाँ हैं विलुप्त नाम

कोड:

const array = [{id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"}],
      names = Object.keys(array.reduce((a, { name }) => (a[name] = 1, a), {}))

console.log(names)


7

कई अच्छे जवाब यहाँ। मैं सिर्फ कुछ विविधता के साथ आपको एक और परिप्रेक्ष्य देने की आशा के साथ योगदान करना चाहूंगा।

जावास्क्रिप्ट में एरेज़ ऑब्जेक्ट प्रकार के होते हैं, इसलिए उन्हें उसी समय हैश के रूप में उपयोग किया जा सकता है। इस कार्यक्षमता का उपयोग करके हम ओ (एन) समय की जटिलता के साथ एक ही कम ऑपरेशन में किए जाने वाले काम को बहुत सरल कर सकते हैं।

यदि आप अपने ऐरे से खुश नहीं हैं, तो ऐरे कीज के अलावा कुछ प्रॉपर्टीज़ को अपने पास रखने के साथ-साथ एक अलग हैश ऑब्जेक्ट रखने पर विचार कर सकते हैं।

var array = [{id:123, value:"value1", name:"Name1"},
             {id:124, value:"value2", name:"Name1"},
             {id:125, value:"value3", name:"Name2"},
             {id:126, value:"value4", name:"Name2"}
            ],
result = array.reduce((p,c) => p[c.name] ? p : (p[c.name] = true, p.push(c.name), p), []);
console.log(result);


इस ES5 समाधान में अच्छा प्रदर्शन है, लेकिन दो उद्देश्यों के लिए सरणी का उपयोग करना भ्रामक है, और खतरनाक है यदि नामों में से एक सिर्फ एक संख्या है। मैं p[c.name]एक अलग ऑब्जेक्ट पर सामान करने की सलाह oदूंगा और फिर बाद में उसे छोड़ दूंगा।
joeytwiddle

7

मैं मानता हूं कि यदि आपको केवल nameमूल्यों की आवश्यकता है , तो Setजाने का रास्ता है।

हालांकि , यदि आप nameसंपत्ति के आधार पर अद्वितीय वस्तुओं की एक सरणी प्राप्त करना चाहते हैं, तो मैं एक का उपयोग करने का सुझाव दूंगा Map। मानचित्र बनाने का एक त्वरित तरीका, [key, value]सारणियों के एक सरणी के माध्यम से है:

const array = [{ id: 123, value: "value1", name:"Name1" }, { id: 124, value: "value2", name: "Name1" }, { id: 125, value: "value3", name: "Name2" }, { id: 126, value: "value4", name: "Name2" }],
      unique = new Map(array.map(obj => [obj.name, obj]));

// To get the unique objects
const uniques = Array.from(unique.values());

// Get the names like you already did:
console.log("Names:", uniques.map(obj => obj.name));

// If you ever need the complete array of unique objects, you got a ref:
console.log(JSON.stringify(uniques));
.as-console-wrapper { min-height: 100%; }

इसका एक अतिरिक्त लाभ Mapयह है कि आप दोनों filterकार्यक्षमता प्राप्त करते हैं जो स्रोत वस्तुओं के साथ संबंध को खोए बिना, गैर-प्राचीन वस्तुओं को काटते हैं। बेशक, यह केवल तभी आवश्यक है जब आपको कई बार वस्तुओं के अद्वितीय सेट को संदर्भित करने की आवश्यकता होती है।



2

ईएस 6 के साथ यह काम करना चाहिए।

var array=[
    {id:123, value:"value1", name:"Name1"},
    {id:124, value:"value2", name:"Name1"},
    {id:125, value:"value3", name:"Name2"},
    {id:126, value:"value4", name:"Name2"}
];

var set = new Set();

array.forEach((a)=>{
    set.add(a.name);
}); 

console.log(Array.from(set));


11
mapइसका उपयोग शुद्ध कार्यों के साथ किया जाना चाहिए, साइड इफेक्ट्स के लिए नहीं। यह forEachया के लिए एक नौकरी होगी reduce
विंसेंट वैन डेर वीले

1

अंडरस्कोरजेस का उपयोग करना,

array = [{id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"}];
get_names =  _.pluck(_.uniq(array, 'name'), 'name')
console.log(get_names)
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

`


0

ES5 में, O ( n ) प्रदर्शन के लिए एक शब्दकोष के रूप में एक वस्तु का उपयोग करें ।

यह तभी काम करेगा जब सभी कीज स्ट्रिंग्स होंगे।

var array = [
    {id: 123, value: "value1", name: "Name1"},
    {id: 124, value: "value2", name: "Name1"},
    {id: 125, value: "value3", name: "Name2"},
    {id: 126, value: "value4", name: "Name2"}
];

var allNames = array.map(item => item.name);

var map = {};
allNames.forEach(name => {
  map[name] = true;
});
var uniqueNames = Object.keys(map);

console.log(uniqueNames);

यदि आप चाहें तो आप एक ही काम कर सकते हैं:

var uniqueNames = Object.keys(allNames.reduce((m, n) => (m[n] = true, m), {}));

लेकिन मुझे पढ़ने के लिए अनिवार्य रूप आसान लगता है।


मैंने स्पष्टता के लिए ES6 तीर फ़ंक्शन का उपयोग किया। यदि आप वास्तव में ES5 को ट्रांसपिलर के बिना लक्षित कर रहे हैं, तो आपको इसके बजाय पूर्ण फ़ॉर्म का उपयोग करने की आवश्यकता होगी:function (item) { return item.name; }
joeytwiddle

एक विकल्प के रूप में Object.keys(), यह उत्तरfilter() केवल उन नामों को रखने के लिए उपयोग करता है जो अभी तक नक्शे में संग्रहीत नहीं किए गए हैं, जो कि बहुत ही सुरुचिपूर्ण है।
joeytwiddle


0

इस तरह के तरीकों array#forEach()और array#indexOf()तरीकों का उपयोग करें यदि आप अभी तक अधिकतम संगतता चाहते हैं , तो वाक्य रचना संक्षिप्त करें:

const array = [{ id: 123, value: "value1", name:"Name1" }, { id: 124, value: "value2", name: "Name1" }, { id: 125, value: "value3", name: "Name2" }, { id: 126, value: "value4", name: "Name2" }]

// initialize an empty array named names
let names = [];

// iterate through every element of `array` & check if it's 'name' key's value already in names array if not ADD it 
array.forEach(function(element) { if (names.indexOf(element.name) === -1) names.push(element.name) });
// or use tilde like this:
//array.forEach(function(element) { if (~names.indexOf(element.name)) names.push(element.name) });

console.log(names);

हालाँकि, यदि संगतता समस्या का उपयोग नहीं करता है ECMAScript 6 की Setवस्तु, array#mapऔर Array.from()इस तरह के तरीके:

const array = [{ id: 123, value: "value1", name:"Name1" }, { id: 124, value: "value2", name: "Name1" }, { id: 125, value: "value3", name: "Name2" }, { id: 126, value: "value4", name: "Name2" }];

// iterate through every element from array using map and store it in Set(a Set won't have duplicates) then convert the Set back to Array(using Array.from)
let names = Array.from(new Set(array.map(element => element.name)));

console.log(names);


0

एक अलग खाली सरणी का उपयोग करते हुए मैंने यह कैसे किया।

var array = [
   {id:123, value:"value1", name:"Name1"},
   {id:124, value:"value2", name:"Name1"},
   {id:125, value:"value3", name:"Name2"},
   {id:126, value:"value4", name:"Name2"}	    
];

var array2 = []		
		
for (i=0; i<array.length;i++){						
   if (array2.indexOf(array[i].name) == -1){				
     array2.push(array[i].name);
    }
}			

console.log(array2)	


-1

1 लाइनर चाहने वालों के लिए

const names = array.reduce((acc, {name}) => acc.includes(name) ? acc : [name, ...acc], []);

या सरणी के प्रोटोटाइप पर विधियों का उपयोग किए बिना

const { reduce, includes } = Array;
const names = reduce(array, (acc, {name}) => includes(acc, name) ? acc : [name, ...acc], []);

इससे निपटने के लिए कुछ शुद्ध कार्य लिखने के लिए उपयोगी हो सकता है

const get_uniq_values = (key, arr) => reduce(arr, (a, o) => includes(a, o[key]) ? a : [o[key], ...a], []);

-1
var __array=[{id:123, value:"value1", name:"Name1"},{id:124, value:"value2", name:"Name1"},{id:125, value:"value3", name:"Name2"},{id:126, value:"value4", name:"Name2"}];

function __checkArray(__obj){
    var flag = true;
    for(let i=0; i < __array.length; i++){
        if(__obj.id == __array.id){
            flag = false;
            break;
        }
    }

    return flag;
}

var __valToPush = {id: 127, value: "value5", name: "Name3"};
if(__checkArray(__valToPush)){
    __array.push(__valToPush)
}

11
क्या आपके पास इतना अंडरस्कोर इस्तेमाल करने का कोई विशेष कारण है?
नीना स्कोल्ज़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.