जावास्क्रिप्ट और डी-डुप्लिकेट आइटम में दो सरणियों का विलय कैसे करें


1364

मेरे पास दो जावास्क्रिप्ट सरणियाँ हैं:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

मैं चाहता हूं कि आउटपुट हो:

var array3 = ["Vijendra","Singh","Shakya"];

आउटपुट सरणी में हटाए गए शब्दों को दोहराया जाना चाहिए।

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


1
नया उत्तर पोस्ट करने से पहले, विचार करें कि इस प्रश्न के लिए पहले से ही 75+ उत्तर हैं। कृपया, सुनिश्चित करें कि आपका उत्तर उन सूचनाओं का योगदान करता है जो मौजूदा उत्तरों में नहीं हैं।
janniks 12

[... नया सेट ([... [१, २, ३], ... [२, ३, ४]]]] परिणाम [१, २, ३, ४]
डेनिस गिफेलर

यदि आप अधिक जेनेरिक समाधान चाहते हैं जो गहरी-विलय को भी कवर करता है, तो इस प्रश्न पर एक नज़र डालें । कुछ उत्तर सरणियों को भी कवर करते हैं।
मार्टिन ब्रौन

जवाबों:


1661

केवल सरणियों को मर्ज करने के लिए (डुप्लिकेट को हटाए बिना)

ES5 संस्करण का उपयोग करें Array.concat:

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];

console.log(array1.concat(array2));

ES6 संस्करण विनाशकारी उपयोग करता है

const array1 = ["Vijendra","Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = [...array1, ...array2];

चूंकि डुप्लिकेट को हटाने के लिए कोई 'इन-बिल्ट' तरीका नहीं है ( ECMA-262 वास्तव में Array.forEachजो इसके लिए बहुत अच्छा होगा), हमें इसे मैन्युअल रूप से करना होगा:

Array.prototype.unique = function() {
    var a = this.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {
            if(a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
};

फिर, इसका उपयोग करने के लिए:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
// Merges both arrays and gets unique items
var array3 = array1.concat(array2).unique(); 

यह सरणियों के क्रम को भी संरक्षित करेगा (अर्थात, किसी प्रकार की छँटाई की आवश्यकता नहीं)।

के बाद से कई लोगों के प्रोटोटाइप वृद्धि के बारे में नाराज कर रहे हैं Array.prototypeऔर for inछोरों, यहाँ इसका इस्तेमाल करने के लिए एक कम आक्रामक तरीका है:

function arrayUnique(array) {
    var a = array.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {
            if(a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
}

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
    // Merges both arrays and gets unique items
var array3 = arrayUnique(array1.concat(array2));

उन लोगों के लिए जो सौभाग्यशाली हैं कि ब्राउज़रों के साथ काम करने के लिए जहां ES5 उपलब्ध है, आप Object.definePropertyइस तरह का उपयोग कर सकते हैं :

Object.defineProperty(Array.prototype, 'unique', {
    enumerable: false,
    configurable: false,
    writable: false,
    value: function() {
        var a = this.concat();
        for(var i=0; i<a.length; ++i) {
            for(var j=i+1; j<a.length; ++j) {
                if(a[i] === a[j])
                    a.splice(j--, 1);
            }
        }

        return a;
    }
});

281
ध्यान दें कि यह एल्गोरिथम O (n ^ 2) है।
गुम्बो

7
आज्ञा देना [a, b, c]और [x, b, d]सरणियाँ (मानें उद्धरण)। समापक देता है [a, b, c, x, b, d]। अद्वितीय () आउटपुट नहीं होगा [a, c, x, b, d]। मुझे लगता है कि आदेश को संरक्षित नहीं करता है - मेरा मानना ​​है कि ओपी चाहता है[a, b, c, x, d]
अमरघोष

89
ओपी ने पहले जवाब को स्वीकार कर लिया जो उसे काम कर रहा था और इस पर हस्ताक्षर किए। हम अभी भी एक-दूसरे के समाधानों की तुलना कर रहे हैं, एन-फिक्सिंग दोषों का पता लगा रहे हैं, प्रदर्शन में सुधार कर रहे हैं, सुनिश्चित करें कि यह हर जगह और इसी तरह से संगत हो ...
स्टैकओवरफ्लो

6
मैंने मूल रूप से इसे वोट दिया था लेकिन मैंने अपना विचार बदल दिया है। प्रोटोटाइप को Array.prototyp में असाइन करने के "बयानों में ... के लिए" तोड़ने के परिणाम हैं। तो सबसे अच्छा समाधान शायद इस तरह के एक फ़ंक्शन का उपयोग करना है लेकिन इसे प्रोटोटाइप के रूप में असाइन नहीं करना है। कुछ लोग तर्क दे सकते हैं कि "फॉर ... इन" कथनों का उपयोग वैसे भी सरणी तत्वों को पुनरावृत्त करने के लिए नहीं किया जाना चाहिए, लेकिन लोग अक्सर उनका उपयोग इस तरह करते हैं कि बहुत कम से कम इस समाधान का उपयोग सावधानी के साथ किया जाए।
कोड कमांडर

16
आप हमेशा का उपयोग करना चाहिए for ... inसाथ hasOwnPropertyजिस स्थिति में प्रोटोटाइप विधि ठीक है
mulllhausen

600

अंडरस्कोर.जे या लो-डैश के साथ आप कर सकते हैं:

console.log(_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

http://underscorejs.org/#union

http://lodash.com/docs#union


70
या, शायद अंडरस्कोर, एपीआई-संगत लॉश से भी बेहतर है ।
ब्रायन एम। हंट

3
@ यश, लॉश डॉक्स से। " आदेश में , एक या अधिक सरणियों में मौजूद हैं, जो अद्वितीय मानों की एक नई सरणी देता है ।"
रिचर्ड अयोटे

4
मैं अंडरस्कोर पसंद करता हूं। जेएस। मैंने underscore.flatten()जो प्रयोग किया वह समाप्त हो गया , जो संघ की तुलना में बेहतर है कि यह एक सारणी लेता है।
बुनकर

8
@weaver _.flatten विलीन हो जाता है, लेकिन 'डी-डुप्लिकेट' नहीं करता है।
गिजजनबी

9
त्वरित प्रदर्शन लॉश को शीर्ष उत्तर पर ले जाता है: jsperf.com/merge-two-arrays-keeping-only-unique-values
slickplaid

288

पहले दो सरणियों को सम्‍मिलित करें, अगला केवल अनन्य आइटम फ़िल्टर करें:

var a = [1, 2, 3], b = [101, 2, 1, 10]
var c = a.concat(b)
var d = c.filter((item, pos) => c.indexOf(item) === pos)

console.log(d) // d is [1, 2, 3, 101, 10]

संपादित करें

जैसा कि सुझाव दिया गया है कि एक अधिक प्रदर्शन वार समाधान अद्वितीय वस्तुओं को बाहर निकालने से bपहले फ़िल्टर करना होगा a:

var a = [1, 2, 3], b = [101, 2, 1, 10]
var c = a.concat(b.filter((item) => a.indexOf(item) < 0))

console.log(c) // c is [1, 2, 3, 101, 10]


5
यहां मूल समाधान में प्रत्येक स्रोत सरणी के भीतर डंप को हटाने का लाभ है। मुझे लगता है कि यह आपके संदर्भ पर निर्भर करता है जिसका आप उपयोग करेंगे।
द जीको

आप IE6- समर्थन के लिए अलग विलय कर सकते हैं: c = Array.from (नया सेट (c));
तोबी जी।

अगर मैं वास्तव aमें जोड़ने के लिए बदलना चाहता हूं b, तो क्या यह पुश से बेहतर होगा और पुश का उपयोग करेगा? a.forEach(function(item){ if(a.indexOf(item)<0) a.push(item); });
विस्मय में

1
IE6 के बारे में उत्सुक लोगों के लिए बस वर्तमान ब्राउज़र उपयोग caniuse.com/usage-table की याद दिलाता है ।
शाम

10
@Andrew: यहां तक कि बेहतर: 1. var c = [...a, ...b.filter(o => !~a.indexOf(o))]; 2. var c = [...new Set([...a, ...b])];
7vujy0f0hy

203

यह प्रसार ऑपरेटर और सरणी जेनेरिक का उपयोग करके एक ECMAScript 6 समाधान है ।

वर्तमान में यह केवल फ़ायरफ़ॉक्स और संभवतः इंटरनेट एक्सप्लोरर तकनीकी पूर्वावलोकन के साथ काम करता है।

लेकिन अगर आप बबेल का उपयोग करते हैं , तो आपके पास यह हो सकता है।

const input = [
  [1, 2, 3],
  [101, 2, 1, 10],
  [2, 1]
];
const mergeDedupe = (arr) => {
  return [...new Set([].concat(...arr))];
}

console.log('output', mergeDedupe(input));


14
इसे स्वीकृत उत्तर में जोड़ा जाना चाहिए। यह समाधान वर्तमान में जितना संभव है उससे कहीं अधिक कुशल और बहुत अधिक सुरुचिपूर्ण है, लेकिन यह वही है जो हम अनिवार्य रूप से करने में सक्षम होंगे (और इस क्षेत्र में बने रहने के लिए क्या करना चाहिए)।
एम्मागमामा

यह ओपी के प्रश्न के समान नहीं है (यह किसी भी चीज़ की तुलना में अधिक सपाट लगता है) लेकिन अपवोट क्योंकि यह कमाल है।
jedd.ahyoung

4
यह कहना मुश्किल है कि यह 2009 से प्रश्न का स्वीकृत उत्तर होना चाहिए। लेकिन हाँ, यह न केवल अधिक "कलाकार" है, बल्कि "सुरुचिपूर्ण" भी है
Cezar Augusto

11
Array.fromप्रसार ऑपरेटर के बजाय इस्तेमाल किया जा सकता है: Array.from(new Set([].concat(...arr)))
हेनरी बेलीथ

1
यह बहुत सुरुचिपूर्ण है। दुर्भाग्य से टाइपस्क्रिप्ट अभी तक इसका समर्थन नहीं करता है। stackoverflow.com/questions/33464504/…
Ben Carp

190

ES6

array1.push(...array2) // => don't remove duplication 

या

[...array1,...array2] //   =>  don't remove duplication 

या

[...new Set([...array1 ,...array2])]; //   => remove duplication

1
1st / 2nd उदाहरण बिल्कुल नहीं है union+ 1 उदाहरण बड़े Arrays + के लिए स्टैक को उड़ाता है + 3rd उदाहरण अविश्वसनीय रूप से धीमा है और बहुत अधिक मेमोरी का उपभोग करता है, क्योंकि दो मध्यवर्ती Arrays का निर्माण किया जाना है + 3 उदाहरण केवल unionएक ज्ञात के साथ उपयोग किया जा सकता है Arrayसंकलन समय पर s की संख्या ।

तो आप इसे कैसे करेंगे?
डेविड नोरना

14
Setयहां जाने का रास्ता है
philk

3
ध्यान दें कि सेट के लिए दो ऑब्जेक्ट्स को एक ही कुंजी जोड़े को तब तक काट नहीं सकते हैं जब तक कि वे एक ही ऑब्जेक्ट संदर्भ न हों।
Jun711

2
वस्तुओं की एक सरणी के साथ काम नहीं करता है, क्योंकि यह केवल ऑब्जेक्ट संदर्भ को मर्ज करेगा और परवाह नहीं करता है यदि ऑब्जेक्ट स्वयं समान हैं।
विल्सन बिग्स

87

सेट (ECMAScript 2015) का उपयोग करना , यह उतना ही सरल होगा:

const array1 = ["Vijendra", "Singh"];
const array2 = ["Singh", "Shakya"];
console.log(Array.from(new Set(array1.concat(array2))));


7
मैं ईएस 6 का उपयोग करने के लिए इस "स्वीकृत उत्तर" पर विचार करता हूं।
mwieczorek

9
@mwieczorek कैसे के बारे में:const array3 = [...new Set(array1.concat(array2))]
रॉबी कॉर्नेलिसन

5
यह काम नहीं करता है अगर आप वस्तुओं का एक सरणी का उपयोग कर रहे हैं
carkod

1
डुप्लिकेट किए बिना विभिन्न ऑब्जेक्ट्स को मर्ज करने के लिए: stackoverflow.com/a/54134237/3131433
रकीबुल हक

38

यहाँ लूप पर थोड़ा अलग है। क्रोम के नवीनतम संस्करण में कुछ अनुकूलन के साथ, यह दो सरणियों (क्रोम 38.0.2111) के संघ को हल करने के लिए सबसे तेज़ तरीका है।

http://jsperf.com/merge-two-arrays-keeping-only-unique-values

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [];

var arr = array1.concat(array2),
  len = arr.length;

while (len--) {
  var itm = arr[len];
  if (array3.indexOf(itm) === -1) {
    array3.unshift(itm);
  }
}

जबकि लूप: ~ 589k ऑप्स / एस
फिल्टर: ~ 445k ऑप्स / एस
लॉश: 308k ऑप्स / एस
लिए 308k ऑप्स / एस: 225k ऑप्स / एस

एक टिप्पणी में कहा गया है कि मेरे सेटअप चर में से एक मेरे लूप को बाकी हिस्सों से आगे खींच रहा था, क्योंकि इसे लिखने के लिए एक खाली सरणी को इनिशियलाइज़ नहीं करना था। मैं इससे सहमत हूं, इसलिए मैंने टेस्ट को फिर से खेल के मैदान में भी लिख दिया है, और इसमें और भी तेज विकल्प शामिल किया है।

http://jsperf.com/merge-two-arrays-keeping-only-unique-values/52

let whileLoopAlt = function (array1, array2) {
    const array3 = array1.slice(0);
    let len1 = array1.length;
    let len2 = array2.length;
    const assoc = {};

    while (len1--) {
        assoc[array1[len1]] = null;
    }

    while (len2--) {
        let itm = array2[len2];

        if (assoc[itm] === undefined) { // Eliminate the indexOf call
            array3.push(itm);
            assoc[itm] = null;
        }
    }

    return array3;
};

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

हर मूल्य (i-1) पर डबल लूप के साथ यहां शीर्ष उत्तर अभी भी काफी धीमा है। लताश अभी भी मजबूत कर रहा है, और मैं अभी भी इसे किसी को भी सुझाएगा जो अपने प्रोजेक्ट में एक पुस्तकालय जोड़ने का मन नहीं करता है। जो लोग नहीं चाहते हैं, उनके लिए मेरा लूप अभी भी एक अच्छा जवाब है और फ़िल्टर उत्तर में यहां बहुत मजबूत दिख रहा है, इस परीक्षण के रूप में नवीनतम कैनरी क्रोम (44.0.2360) के साथ मेरे परीक्षणों पर सभी को हराकर।

की जाँच करें माइक जवाब और दान Stocker का जवाब यदि आप गति में यह एक पायदान कदम अप करना चाहते हैं। वे लगभग सभी व्यवहार्य उत्तरों के माध्यम से जाने के बाद सभी परिणामों में सबसे तेज़ हैं।


आपकी कार्यप्रणाली में एक दोष है: आप array3 के निर्माण को सेटअप चरण में डालते हैं, जबकि यह लागत केवल आपके समय-आधारित समाधान के स्कोर का हिस्सा होनी चाहिए। इस 1 पंक्ति के चले जाने से , आपका समाधान लूप आधारित एक की गति पर गिर जाता है। मैं समझता हूं कि सरणी का पुन: उपयोग किया जा सकता है, लेकिन हो सकता है कि अन्य एल्गोरिदम भी प्रत्येक आवश्यक बिल्डिंग ब्लॉक को घोषित करने और आरंभ करने में लाभ न उठाएं।
doldt

मैं आपके आधार @doldt से सहमत हूं, लेकिन आपके परिणामों से असहमत हूं। प्रविष्टियों के लूप आधारित हटाने के साथ एक मौलिक डिजाइन दोष है, इसमें आपको आइटम निकालने के बाद सरणी की लंबाई को फिर से जांचना होगा, जिसके परिणामस्वरूप धीमी निष्पादन समय होगा। जबकि पीछे की ओर काम करने वाले लूप में ये प्रभाव नहीं होते हैं। यहाँ कई सेटअप चर को हटाने के साथ एक उदाहरण दिया गया है क्योंकि मैं उनके मूल उत्तर को बहुत अधिक बदले बिना कर सकता हूं: jsperf.com/merge-two-arrays-keeping-only-unique-values/19
slickplaid

@slickplaid लिंक किए गए परीक्षण खाली हैं, और jsperf में अगला संशोधन लूप में है।
doldt

@doldt मैंने अपने जवाब में आपकी चिंताओं को संबोधित किया है और साथ ही साथ एक उचित अद्यतन परीक्षण भी जोड़ा है। मुझे पता है कि आप उन परिणामों से सहमत हैं या नहीं। साथ ही, मैंने एक साहचर्य सरणी का उपयोग करके एक और बेहतर परिणाम जोड़ा।
slickplaid

1
@slickplaid विस्तारित पूर्ण पृष्ठ की स्थापना के लिए धन्यवाद। जब तक मैं कुछ याद नहीं कर रहा हूँ, तब तक "जबकि weelopAlt2" फ़ंक्शन काम नहीं करता है? यह एक नया सरणी बनाता है जिसमें पहला सरणी है, और दूसरा सरणी (रिवर्स ऑर्डर में) है। भ्रम से बचने के लिए मैंने एक और संशोधन किया है जो टूटे हुए फ़ंक्शन को हटाता है। मैंने एक अतिरिक्त उदाहरण भी जोड़ा: jsperf.com/merge-two-arrays-keeping-only-unique-values/22
स्टीफन एस

37

आप इसे केवल ECMAScript 6,

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [...new Set([...array1 ,...array2])];
console.log(array3); // ["Vijendra", "Singh", "Shakya"];
  • सरणी को सुगम बनाने के लिए प्रसार ऑपरेटर का उपयोग करें ।
  • तत्वों का एक अलग सेट बनाने के लिए सेट का उपयोग करें
  • फिर से सेट सरणी में बदलने के लिए फैल ऑपरेटर का उपयोग करें।

2
मुझे त्रुटि मिलती है: टाइप करें 'सेट करें <string>' कोई अरै टाइप नहीं है।
गैट्सब्रिज

3
और अगर आप किसी कारण से प्रसार ऑपरेटर का उपयोग नहीं करना चाहते हैं, तो यह भी है Array.from(new Set(array1.concat(array2))):।
kba

@gattsbr, में टाइपप्रति साथ tsconfig.json, आप जोड़ सकते हैं "downlevelIteration": trueकरने के लिए compilerOptions
VincentPerrin.com

19
Array.prototype.merge = function(/* variable number of arrays */){
    for(var i = 0; i < arguments.length; i++){
        var array = arguments[i];
        for(var j = 0; j < array.length; j++){
            if(this.indexOf(array[j]) === -1) {
                this.push(array[j]);
            }
        }
    }
    return this;
};

एक बहुत बेहतर सरणी मर्ज फ़ंक्शन।


4
var test = ['a', 'b', 'c']; console.log(test); प्रिंट करेंगे ["a", "b", "c", merge: function]
डौबिडाउ

उत्कृष्ट समाधान। मैंने @slickplaid ( jsperf.com/merge-two-arrays-keeping-only-unique-values/3 ) द्वारा ऊपर पोस्ट किए गए jsperf टेस्ट को अपडेट किया है और ऐसा लगता है कि यह उनमें से सबसे तेज़ है।
कोबरा

@ कोबरा साउंडिंग पेटीएम के जोखिम में, क्रोम 40.0.2214 पर चल रहा है (नवीनतम 2/18/15 के रूप में), यह जवाब मेरा की तुलना में 53% धीमा है। OTOH IE11 मेरे जवाब के लिए बिल्कुल भी अनुकूलित नहीं लगता है। :) क्रोम मोबाइल अभी भी इसे हिला रहा है, हालांकि। ईमानदारी से, यदि आप लॉश / _ का उपयोग कर रहे हैं, जो कि हम में से अधिकांश को चाहिए, तो इस सूची में सही उत्तर पहले से ही बहुत ऊपर है। :)
slickplaid

@slickplaid ट्रू, और यह काफी तेज है, यहां तक ​​कि लॉश / _ एक की तुलना में। मैं शायद अपने कार्यान्वयन को एक बिंदु पर या किसी अन्य को आपके समान करने पर स्विच करूंगा। : डी
कोबरा

1
यह सुनिश्चित नहीं है कि इंडेक्सऑफ () विधि की लागत क्या है, लेकिन यह संभवतः सबसे तेज ES5 संगत विधि है। इसके अलावा कुछ भी नहीं है कि तर्कों की चर लंबाई की आवश्यकता नहीं है। यह तरीका चेनेबल है। @slickplaid लोडिंग लाइब्रेरी कभी भी "जावास्क्रिप्ट में इसे कैसे करें" सवाल का जवाब नहीं है। निश्चित रूप से कई पुस्तकालयों के लिए यह 7 लाइनें काम पाने का एक कार्य है।
देहरादून

19

बस अपने दो सेंट में फेंक रहा हूं।

function mergeStringArrays(a, b){
    var hash = {};
    var ret = [];

    for(var i=0; i < a.length; i++){
        var e = a[i];
        if (!hash[e]){
            hash[e] = true;
            ret.push(e);
        }
    }

    for(var i=0; i < b.length; i++){
        var e = b[i];
        if (!hash[e]){
            hash[e] = true;
            ret.push(e);
        }
    }

    return ret;
}

यह एक ऐसी विधि है जिसका मैं बहुत उपयोग करता हूं, यह डुप्लीकेट चेकिंग करने के लिए हैशपेन टेबल के रूप में एक ऑब्जेक्ट का उपयोग करता है। यह मानते हुए कि हैश O (1) है, तो यह O (n) में चलता है, जहाँ n a.length + b.length है। मुझे ईमानदारी से पता नहीं है कि ब्राउज़र हैश कैसे करता है, लेकिन यह कई हजारों डेटा बिंदुओं पर अच्छा प्रदर्शन करता है।


बहुत अच्छी तरह से किया। इस पृष्ठ पर अन्य परिणामों के काफी (यदि सभी नहीं) बीट्स को साहचर्य सरणी का लाभ उठाकर और indexOf और अन्य कार्यों के लूपिंग को बाहर रखते हुए। jsperf.com/merge-two-arrays-keeping-only-unique-values/21
slickplaid

आपका "हैश" String()जावास्क्रिप्ट में फ़ंक्शन है। जो आदिम मूल्यों (प्रकारों के बीच टकराव के साथ) के लिए काम कर सकता है, लेकिन यह वस्तुओं के सरणियों के लिए एक अच्छा फिट नहीं है।
बर्गी

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

19

नेस्टेड लूप्स (O (n ^ 2)), और .indexOf()(+ O (n)) के बिल्कुल स्पष्ट ।

function merge(a, b) {
    var hash = {}, i;
    for (i=0; i<a.length; i++) {
        hash[a[i]]=true;
    } 
    for (i=0; i<b.length; i++) {
        hash[b[i]]=true;
    } 
    return Object.keys(hash);
}

2
यह बहुत आश्चर्यजनक है, खासकर अगर आप तार कर रहे हैं। संख्याओं को इस तरह रखने के लिए एक अतिरिक्त कदम की आवश्यकता होगी। यदि आप बुरा नहीं मानते हैं, तो यह फ़ंक्शन अन्य सभी विकल्पों को पूरी तरह से हरा देता है, जो आपके समाप्त होने के बाद सब कुछ एक स्ट्रिंग है। अच्छी नौकरी। यहाँ प्रदर्शन के परिणाम: jsperf.com/merge-two-arrays-keeping-only-unique-values/21
slickplaid

18

इस उत्तर को सरल बनाया और इसे एक अच्छे कार्य में बदल दिया:

function mergeUnique(arr1, arr2){
    return arr1.concat(arr2.filter(function (item) {
        return arr1.indexOf(item) === -1;
    }));
}

2
मेरा मानना ​​है कि यह स्वीकृत उत्तर की तुलना में बहुत साफ है। इसके अलावा ऐसा लगता है कि फ़िल्टर ECMAScript 5.1 + में समर्थित है जो अब बहुत समर्थित है।
टॉम फोबियर

यह स्वीकार किया जाना चाहिए था
वालप

यह बहुत अधिक रसीला है।
मोक्स

15

आप किसी वस्तु का उपयोग क्यों नहीं करते? ऐसा लगता है कि आप एक सेट को मॉडल करने की कोशिश कर रहे हैं। हालाँकि, यह आदेश को संरक्षित नहीं करेगा।

var set1 = {"Vijendra":true, "Singh":true}
var set2 = {"Singh":true,  "Shakya":true}

// Merge second object into first
function merge(set1, set2){
  for (var key in set2){
    if (set2.hasOwnProperty(key))
      set1[key] = set2[key]
  }
  return set1
}

merge(set1, set2)

// Create set from array
function setify(array){
  var result = {}
  for (var item in array){
    if (array.hasOwnProperty(item))
      result[array[item]] = true
  }
  return result
}

क्या आपका मतलब नहीं है if (!set1.hasOwnProperty(key))?
गुम्बो

2
मैं ऐसा क्यों कहूंगा? उस स्थिति का उद्देश्य उन गुणों की उपेक्षा करना है जो ऑब्जेक्ट के प्रोटोटाइप में हो सकते हैं।
निक रिटालैक

12

सबसे अच्छा समाधान...

आप सीधे ब्राउज़र कंसोल में चेक करके देख सकते हैं ...

बिना नकल के

a = [1, 2, 3];
b = [3, 2, 1, "prince"];

a.concat(b.filter(function(el) {
    return a.indexOf(el) === -1;
}));

नकल के साथ

["prince", "asish", 5].concat(["ravi", 4])

यदि आप डुप्लिकेट के बिना चाहते हैं तो आप यहां से एक बेहतर समाधान की कोशिश कर सकते हैं - चिल्ला कोड

[1, 2, 3].concat([3, 2, 1, "prince"].filter(function(el) {
    return [1, 2, 3].indexOf(el) === -1;
}));

Chrome ब्राउज़र कंसोल पर प्रयास करें

 f12 > console

आउटपुट:

["prince", "asish", 5, "ravi", 4]

[1, 2, 3, "prince"]

यह आउटपुट ऐरे से डुप्लिकेट नहीं निकालता है।
शाहर

9

मेरा डेढ़ पैसा:

Array.prototype.concat_n_dedupe = function(other_array) {
  return this
    .concat(other_array) // add second
    .reduce(function(uniques, item) { // dedupe all
      if (uniques.indexOf(item) == -1) {
        uniques.push(item);
      }
      return uniques;
    }, []);
};

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

var result = array1.concat_n_dedupe(array2);

console.log(result);

यह कुछ भी है कि ES6 में नया है का उपयोग नहीं करता है, मैं कुछ याद किया?
बर्गी

@ बर्गी: जी, आप सही कह रहे हैं। ध्यान देने के लिए धन्यवाद। किसी तरह मैं इस स्क्रिप्ट के साथ खेल रहा था और शायद ईएस 6 फ़ंक्शन के साथ कुछ संस्करण था, लेकिन अब इसमें इंडेक्सऑफ शामिल है जो सदियों से है। मेरी गलती, क्षमा करें।
हीरो Qu

8

आप इसे केवल अंडरस्कोर का उपयोग करके प्राप्त कर सकते हैं। js का => यूनीक :

array3 = _.uniq(array1.concat(array2))

console.log(array3)

यह ["विजेंद्र", "सिंह", "शाक्य"] छापेगा ।


7

ES6 के लिए, बस एक पंक्ति:

a = [1, 2, 3, 4]
b = [4, 5]
[...new Set(a.concat(b))]  // [1, 2, 3, 4, 5]

7

मुझे पता है कि यह सवाल वस्तुओं की सरणी के बारे में नहीं है, लेकिन खोजकर्ता यहां समाप्त होते हैं।

इसलिए यह भविष्य के पाठकों के लिए विलय का एक उचित ईएस 6 तरीका है और फिर डुप्लिकेट को हटाने के लायक है

वस्तुओं की सरणी :

var arr1 = [ {a: 1}, {a: 2}, {a: 3} ];
var arr2 = [ {a: 1}, {a: 2}, {a: 4} ];

var arr3 = arr1.concat(arr2.filter( ({a}) => !arr1.find(f => f.a == a) ));

// [ {a: 1}, {a: 2}, {a: 3}, {a: 4} ]

6
//Array.indexOf was introduced in javascript 1.6 (ECMA-262) 
//We need to implement it explicitly for other browsers, 
if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt, from)
  {
    var len = this.length >>> 0;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}
//now, on to the problem

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

var merged = array1.concat(array2);
var t;
for(i = 0; i < merged.length; i++)
  if((t = merged.indexOf(i + 1, merged[i])) != -1)
  {
    merged.splice(t, 1);
    i--;//in case of multiple occurrences
  }

indexOfअन्य ब्राउज़रों के लिए विधि का कार्यान्वयन एमडीसी से लिया गया है


1
मुझे यह w3schools में नहीं मिला, इसलिए मैंने इसे लिखा है। w3schools.com/jsref/jsref_obj_array.asp क्या यह fromपैरामीटर btw लेता है ?
अमरघोष

धन्यवाद @Gumbo और @meder - अब मेरे बुकमार्क बदलने जा रहे हैं। मैं अभी तक js में कुछ भी गंभीर नहीं हूं और मैं आकस्मिक संदर्भ के लिए w3schools का उपयोग करता हूं (यही कारण है कि मुझे कभी भी आवश्यकता है) - यही कारण है कि मुझे इसका एहसास नहीं हुआ।
अमरघोष

MDC का कहना है कि indexOf को जावास्क्रिप्ट 1.6 की आवश्यकता है। क्या यह मान लेना सुरक्षित होगा कि आम ब्राउज़र (> = FF2,> IE6 आदि) इसका समर्थन करेंगे?
अमरघोष

4
IE6 Array.prototype.indexOf का समर्थन नहीं करता है, बस मोज़िला द्वारा दी गई समर्थन पद्धति को पेस्ट करें ताकि IE कोई त्रुटि न फेंके।
पदक विजेता

का उपयोग कर अद्यतन indexOf। टिप्पणी वाले हिस्से को हटाकर कोड को साफ किया। @meder - फिर से धन्यवाद।
अमरघोष

6

नया समाधान (जो उपयोग करता है Array.prototype.indexOfऔर Array.prototype.concat):

Array.prototype.uniqueMerge = function( a ) {
    for ( var nonDuplicates = [], i = 0, l = a.length; i<l; ++i ) {
        if ( this.indexOf( a[i] ) === -1 ) {
            nonDuplicates.push( a[i] );
        }
    }
    return this.concat( nonDuplicates )
};

उपयोग:

>>> ['Vijendra', 'Singh'].uniqueMerge(['Singh', 'Shakya'])
["Vijendra", "Singh", "Shakya"]

Array.prototype.indexOf (इंटरनेट एक्सप्लोरर के लिए):

Array.prototype.indexOf = Array.prototype.indexOf || function(elt)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0) ? Math.ceil(from): Math.floor(from); 
    if (from < 0)from += len;

    for (; from < len; from++)
    {
      if (from in this && this[from] === elt)return from;
    }
    return -1;
  };

@ प्रस्तुतकर्ता: यदि आदेश कोई मायने नहीं रखता है तो मैं यह कैसे करता हूँ
विजेंद्र

1
यह Array.prototype के लिए परिभाषित एक मानक ECMAScript विधि नहीं है, हालांकि मैं जानता हूँ कि आप इसे IE और अन्य ब्राउज़रों के लिए आसानी से परिभाषित कर सकते हैं जो इसका समर्थन नहीं करते हैं।
पदक विजेता

ध्यान दें कि यह एल्गोरिथम O (n ^ 2) है।
गुम्बो

आपका उत्तर क्या एल्गोरिथ्म है?
पदक विजेता

@meder: मेरा एल्गोरिथ्म एक यूनियन एल्गोरिथ्म है। संघ स्वयं O (n + m) में किया जाता है, लेकिन छँटाई अधिकांश O (n · log n + m · log m) पर होती है। तो पूरा एल्गोरिथ्म हे (n · log n + m · log m)।
गुम्बो

6

यह सेट का उपयोग करके किया जा सकता है।

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

var array3 = array1.concat(array2);
var tempSet = new Set(array3);
array3 = Array.from(tempSet);

//show output
document.body.querySelector("div").innerHTML = JSON.stringify(array3);
<div style="width:100%;height:4rem;line-height:4rem;background-color:steelblue;color:#DDD;text-align:center;font-family:Calibri" > 
  temp text 
</div>


6

दो सरणियों के विलय के लिए बहुत सारे समाधान हैं। उन्हें दो मुख्य श्रेणियों में विभाजित किया जा सकता है (लॉश या अंडरस्कोर की तरह 3 पार्टी लाइब्रेरी के उपयोग को छोड़कर)।

क) दो सरणियों को मिलाएं और डुप्लिकेट आइटम हटा दें।

बी) उन्हें संयोजित करने से पहले आइटमों को फ़िल्टर करें।

दो सरणियों को मिलाएं और नकली वस्तुओं को हटा दें

का मेल

// mutable operation(array1 is the combined array)
array1.push(...array2);
array1.unshift(...array2);

// immutable operation
const combined = array1.concat(array2);
const combined = [...array1, ...array2];    // ES6

एकीकृत

किसी सरणी को एकीकृत करने के कई तरीके हैं, मैं व्यक्तिगत रूप से दो तरीकों से नीचे का सुझाव देता हूं।

// a little bit tricky
const merged = combined.filter((item, index) => combined.indexOf(item) === index);
const merged = [...new Set(combined)];

उन्हें संयोजित करने से पहले आइटमों को फ़िल्टर करें

कई तरीके भी हैं, लेकिन मैं व्यक्तिगत रूप से इसकी सादगी के कारण नीचे दिए गए कोड का सुझाव देता हूं।

const merged = array1.concat(array2.filter(secItem => !array1.includes(secItem)));

5
Array.prototype.add = function(b){
    var a = this.concat();                // clone current object
    if(!b.push || !b.length) return a;    // if b is not an array, or empty, then return a unchanged
    if(!a.length) return b.concat();      // if original is empty, return b

    // go through all the elements of b
    for(var i = 0; i < b.length; i++){
        // if b's value is not in a, then add it
        if(a.indexOf(b[i]) == -1) a.push(b[i]);
    }
    return a;
}

// Example:
console.log([1,2,3].add([3, 4, 5])); // will output [1, 2, 3, 4, 5]

5
array1.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)

इस एक के बारे में अच्छी बात यह है कि आप सामान्य रूप से, जब आप सरणियों के साथ काम कर रहे हैं, तो फिल्टर, मानचित्र, आदि जैसी विधियों का उपयोग कर रहे हैं, ताकि आप उस रेखा को जोड़ सकें और यह सरणी 1 के साथ सरणी 2 के साथ संक्षिप्त और संक्षिप्त हो जाएगा। एक (जब आप उन तरीकों का पीछा कर रहे हैं जो आपके पास नहीं हैं), उदाहरण:

someSource()
.reduce(...)
.filter(...)
.map(...) 
// and now you want to concat array2 and deduplicate:
.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)
// and keep chaining stuff
.map(...)
.find(...)
// etc

(मुझे Array.prototype को प्रदूषित करना पसंद नहीं है और यह श्रृंखला का सम्मान करने का एकमात्र तरीका होगा - एक नए फ़ंक्शन को परिभाषित करने से यह टूट जाएगा - इसलिए मुझे लगता है कि ऐसा कुछ ऐसा है जो केवल उपलब्धि का एकमात्र तरीका है)



3

ES2015 के साथ एक कार्यात्मक दृष्टिकोण

कार्यात्मक दृष्टिकोण के बाद unionदो Arrayएस की रचना सिर्फ concatऔर की है filter। इष्टतम प्रदर्शन प्रदान करने के लिए हम मूल Setडेटा प्रकार का सहारा लेते हैं , जो कि प्रॉपर्टी लुकअप के लिए अनुकूलित है।

वैसे भी, एक unionफ़ंक्शन के साथ संयोजन में महत्वपूर्ण सवाल यह है कि डुप्लिकेट का इलाज कैसे किया जाए। निम्नलिखित क्रमपरिवर्तन संभव हैं:

Array A      + Array B

[unique]     + [unique]
[duplicated] + [unique]
[unique]     + [duplicated]
[duplicated] + [duplicated]

पहले दो क्रमांकन एकल फ़ंक्शन के साथ संभालना आसान है। हालाँकि, अंतिम दो अधिक जटिल हैं, क्योंकि आप उन्हें तब तक संसाधित नहीं कर सकते जब तक आप Setलुकअप पर भरोसा करते हैं । चूंकि पुरानी पुरानी Objectप्रॉपर्टी लुक्स पर स्विच करने से गंभीर प्रदर्शन होता है, इसलिए निम्नलिखित कार्यान्वयन में तीसरे और चौथे क्रमांक की अनदेखी होती है। आपको unionउनका समर्थन करने के लिए एक अलग संस्करण बनाना होगा।


// small, reusable auxiliary functions

const comp = f => g => x => f(g(x));
const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const afrom = apply(Array.from);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// de-duplication

const dedupe = comp(afrom) (createSet);


// the actual union function

const union = xs => ys => {
  const zs = createSet(xs);  
  return concat(xs) (
    filter(x => zs.has(x)
     ? false
     : zs.add(x)
  ) (ys));
}


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];


// here we go

console.log( "unique/unique", union(dedupe(xs)) (ys) );
console.log( "duplicated/unique", union(xs) (ys) );

यहाँ से यह एक unionnफ़ंक्शन को लागू करने के लिए तुच्छ हो जाता है , जो किसी भी संख्या में सरणियों को स्वीकार करता है (naomik की टिप्पणियों से प्रेरित):

// small, reusable auxiliary functions

const uncurry = f => (a, b) => f(a) (b);
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc);

const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// union and unionn

const union = xs => ys => {
  const zs = createSet(xs);  
  return concat(xs) (
    filter(x => zs.has(x)
     ? false
     : zs.add(x)
  ) (ys));
}

const unionn = (head, ...tail) => foldl(union) (head) (tail);


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];
const zs = [0,1,2,3,4,5,6,7,8,9];


// here we go

console.log( unionn(xs, ys, zs) );

यह पता चला है unionnकि सिर्फ foldl(उर्फ Array.prototype.reduce) है, जो unionअपने reducer के रूप में लेता है । ध्यान दें: चूंकि कार्यान्वयन एक अतिरिक्त संचायक का उपयोग नहीं करता है, जब आप इसे बिना तर्क के लागू करते हैं तो यह एक त्रुटि फेंक देगा।


1
एक जोड़े को फीडबैक: मुझे लगता है कि देखा flipऔर notfअप्रयुक्त हैं। इसके अलावा unionByलीक के कार्यान्वयन के विवरण की भविष्यवाणी करें ( Setप्रकार के निहित ज्ञान की आवश्यकता है )। यह अच्छा हो सकता है यदि आप बस कुछ ऐसा कर सकते हैं: union = unionBy (apply)और unionci = unionBy (p => x => p(x.toLowerCase()))। इस तरह से उपयोगकर्ता जो भी समूहीकरण मूल्य भेजता है वह है p- बस एक विचार ^ _ ^
धन्यवाद

zsपरिवर्तनीय घोषणा में भी कमी है var/ letखोजशब्द
धन्यवाद

1
यहाँ एक कोड स्निपेट स्पष्ट करने के लिए है [gist: UnionBy.js ]
धन्यवाद

@naomik थोड़ी देर के लिए अपने समाधान पर पुनर्विचार करने के बाद मुझे अब और यकीन नहीं है, अगर यह विधेय को पारित करने का सही तरीका है। आप सभी लाभ दूसरे सरणी के प्रत्येक तत्व का एक परिवर्तन है। मुझे आश्चर्य है कि अगर यह दृष्टिकोण सिर्फ खिलौना समस्याओं से अधिक हल करता है।

3

इसके लिए ... यहाँ एक पंक्ति समाधान है:

const x = [...new Set([['C', 'B'],['B', 'A']].reduce( (a, e) => a.concat(e), []))].sort()
// ['A', 'B', 'C']

विशेष रूप से पठनीय नहीं है, लेकिन यह किसी की मदद कर सकता है:

  1. एक खाली सरणी के लिए सेट प्रारंभिक संचायक मान के साथ एक कम फ़ंक्शन लागू करता है।
  2. कम फ़ंक्शन संचयकर्ता सरणी पर प्रत्येक उप-सरणी को जोड़ने के लिए कॉनैट का उपयोग करता है।
  3. इसका परिणाम एक नया बनाने के लिए एक निर्माण पैरामीटर के रूप में पारित किया जाता है Set
  4. Setकिसी सरणी को बदलने के लिए स्प्रेड ऑपरेटर का उपयोग किया जाता है ।
  5. sort()समारोह नई सरणी लिए आवेदन किया है।

2
इसके अलावा reduce()आप का उपयोग कर सकते हैंArray.from(set)
Eran Goldin

3

DeDuplicate एकल या मर्ज और DeDuplicate कई सरणी इनपुट। नीचे उदाहरण है।

ES6 का उपयोग - सेट, के लिए, विनाशकारी

मैंने यह सरल फ़ंक्शन लिखा है जो कई सरणी तर्क लेता है। बहुत अधिक वही करता है जो इसके ऊपर के समाधान के रूप में अधिक व्यावहारिक उपयोग का मामला है। यह फ़ंक्शन डुप्लिकेट मानों को केवल एक सरणी में समेटता नहीं है, ताकि यह बाद के चरण में उन्हें हटा सके।

शॉर्ट फंक्शन डिप्रेशन (केवल 9 लाइनें)

/**
* This function merging only arrays unique values. It does not merges arrays in to array with duplicate values at any stage.
*
* @params ...args Function accept multiple array input (merges them to single array with no duplicates)
* it also can be used to filter duplicates in single array
*/
function arrayDeDuplicate(...args){
   let set = new Set(); // init Set object (available as of ES6)
   for(let arr of args){ // for of loops through values
      arr.map((value) => { // map adds each value to Set object
         set.add(value); // set.add method adds only unique values
      });
   }
   return [...set]; // destructuring set object back to array object
   // alternativly we culd use:  return Array.from(set);
}

उपयोग उदाहरण CODEPEN :

// SCENARIO 
let a = [1,2,3,4,5,6];
let b = [4,5,6,7,8,9,10,10,10];
let c = [43,23,1,2,3];
let d = ['a','b','c','d'];
let e = ['b','c','d','e'];

// USEAGE
let uniqueArrayAll = arrayDeDuplicate(a, b, c, d, e);
let uniqueArraySingle = arrayDeDuplicate(b);

// OUTPUT
console.log(uniqueArrayAll); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 43, 23, "a", "b", "c", "d", "e"]
console.log(uniqueArraySingle); // [4, 5, 6, 7, 8, 9, 10]

arr.mapयहाँ क्यों उपयोग करें? आप इसे एक के रूप में उपयोग कर रहे हैं foreach, क्योंकि परिणाम की अनदेखी की गई है
एंटनी

मैंने Array.from (set.values ​​()) का उपयोग किया; , क्योंकि vscode रिटर्न के
मक्की


3

var array1 = ["one","two"];
var array2 = ["two", "three"];
var collectionOfTwoArrays = [...array1, ...array2];    
var uniqueList = array => [...new Set(array)];
console.log('Collection :');
console.log(collectionOfTwoArrays);    
console.log('Collection without duplicates :');
console.log(uniqueList(collectionOfTwoArrays));

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