javascript - किसी सरणी में सभी अद्वितीय मान प्राप्त करें(डुप्लिकेट हटाएं)




arrays unique (20)

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

तो मुझे सीखने में मदद करने के लिए, क्या कोई मुझे यह निर्धारित करने में मदद कर सकता है कि प्रोटोटाइप स्क्रिप्ट गलत कहां जा रही है?

Array.prototype.getUnique = function() {
 var o = {}, a = [], i, e;
 for (i = 0; e = this[i]; i++) {o[e] = 1};
 for (e in o) {a.push (e)};
 return a;
}

डुप्लिकेट प्रश्न से अधिक जवाब:

इसी तरह का सवाल:


एक लाइनर, शुद्ध जावास्क्रिप्ट

ES6 वाक्यविन्यास के साथ

list = list.filter((x, i, a) => a.indexOf(x) == i)

x --> item in array
i --> index of item
a --> array reference, (in this case "list")

ES5 वाक्यविन्यास के साथ

list = list.filter(function (x, i, a) { 
    return a.indexOf(x) == i; 
});

ब्राउज़र संगतता : IE9 +


Array.prototype को विस्तारित किए बिना (इसे एक बुरा अभ्यास कहा जाता है) या jquery / underscore का उपयोग करके, आप केवल सरणी filter कर सकते हैं।

अंतिम घटना को रखते हुए:

    function arrayLastUnique(array) {
        return array.filter(function (a, b, c) {
            // keeps last occurrence
            return c.indexOf(a, b + 1) < 0;
        });
    },

या पहली घटना:

    function arrayFirstUnique(array) {
        return array.filter(function (a, b, c) {
            // keeps first occurrence
            return c.indexOf(a) === b;
        });
    },

खैर, यह केवल जावास्क्रिप्ट ईसीएमएस्क्रिप्ट 5+ है, जिसका अर्थ केवल आईई 9 + है, लेकिन यह देशी एचटीएमएल / जेएस (विंडोज स्टोर ऐप, फ़ायरफ़ॉक्स ओएस, सेन्चा, फोनगैप, टाइटेनियम, ...) में विकास के लिए अच्छा है।


es6 के साथ (और आदेश बनाए रखता है):

[...new Set(myArray)];

अगर कोई knockoutjs का उपयोग कर रहा है

ko.utils.arrayGetDistinctValues()

बीटीडब्ल्यू ने सभी ko.utils.array* उपयोगिताएं ko.utils.array* हैं।


आप underscore.js भी उपयोग कर सकते हैं।

console.log(_.uniq([1, 2, 1, 3, 1, 4]));
<script src="http://underscorejs.org/underscore-min.js"></script>

जो वापस आ जाएगा:

[1, 2, 3, 4]

आप jQuery का भी उपयोग कर सकते हैं

var a = [1,5,1,6,4,5,2,5,4,3,1,2,6,6,3,3,2,4];

// note: jQuery's filter params are opposite of javascript's native implementation :(
var unique = $.makeArray($(a).filter(function(i,itm){ 
    // note: 'index', not 'indexOf'
    return i == $(a).index(itm);
}));

// unique: [1, 5, 6, 4, 2, 3]

मूल रूप से उत्तर दिया: jQuery सरणी एक सरणी से सभी अद्वितीय तत्व प्राप्त करने के लिए?


ऐसा इसलिए है क्योंकि 0 जावास्क्रिप्ट में एक झूठा मूल्य है।

this[i] गलत होगा यदि सरणी का मान 0 या कोई अन्य गलत मूल्य है।


ऐसा करने का सबसे आसान, और fastest (क्रोम में) तरीका:

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

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

जेएस पेर्फ के अनुसार, यह फ़ंक्शन fastest - हालांकि अपना खुद का जोड़ना स्वतंत्र महसूस करें।

गैर-प्रोटोटाइप संस्करण:

function uniques(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.push(arr[i]);
    return a;
}

छंटाई

सरणी को सॉर्ट करने की भी आवश्यकता होने पर, निम्नतम सबसे तेज़ है:

Array.prototype.sortUnique = function() {
    this.sort();
    var last_i;
    for (var i=0;i<this.length;i++)
        if ((last_i = this.lastIndexOf(this[i])) !== i)
            this.splice(i+1, last_i-i);
    return this;
}

या गैर प्रोटोटाइप:

function sortUnique(arr) {
    arr.sort();
    var last_i;
    for (var i=0;i<arr.length;i++)
        if ((last_i = arr.lastIndexOf(arr[i])) !== i)
            arr.splice(i+1, last_i-i);
    return arr;
}

यह अधिकांश गैर-क्रोम ब्राउज़र में fastest भी fastest


मुझे एहसास है कि इस प्रश्न में 30 से अधिक उत्तरों पहले से ही हैं। लेकिन मैंने पहले सभी मौजूदा उत्तरों के माध्यम से पढ़ा है और अपना खुद का शोध किया है।

मैंने सभी उत्तरों को 4 संभावित समाधानों में विभाजित किया:

  1. नई ES6 सुविधा का उपयोग करें: [...new Set( [1, 1, 2] )];
  2. डुप्लिकेट को रोकने के लिए ऑब्जेक्ट { } का उपयोग करें
  3. सहायक सरणी का प्रयोग करें [ ]
  4. filter + indexOf प्रयोग करें

उत्तर में पाए गए नमूना कोड यहां दिए गए हैं:

नई ES6 सुविधा का उपयोग करें: [...new Set( [1, 1, 2] )];

function uniqueArray0(array) {
  var result = Array.from(new Set(array));
  return result    
}

डुप्लिकेट को रोकने के लिए ऑब्जेक्ट { } का उपयोग करें

function uniqueArray1( ar ) {
  var j = {};

  ar.forEach( function(v) {
    j[v+ '::' + typeof v] = v;
  });

  return Object.keys(j).map(function(v){
    return j[v];
  });
} 

सहायक सरणी का प्रयोग करें [ ]

function uniqueArray2(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.push(arr[i]);
    return a;
}

filter + indexOf प्रयोग करें

function uniqueArray3(a) {
  function onlyUnique(value, index, self) { 
      return self.indexOf(value) === index;
  }

  // usage
  var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']

  return unique;
}

और मैंने सोचा कि कौन सा तेज है। मैंने कार्यों का परीक्षण करने के लिए नमूना Google शीट बनाया है। नोट: ईसीएमए 6 Google शीट्स में उपलब्ध नहीं है, इसलिए मैं इसका परीक्षण नहीं कर सकता।

परीक्षणों का नतीजा यहां दिया गया है:

मुझे यह देखने की उम्मीद है कि ऑब्जेक्ट { } का उपयोग करके कोड जीत जाएगा क्योंकि यह हैश का उपयोग करता है। इसलिए मुझे खुशी है कि परीक्षणों ने क्रोम और आईई में इस एल्गोरिदम के लिए सर्वोत्तम परिणाम दिखाए। कोड के लिए @rab के लिए धन्यवाद।


मुझे यकीन नहीं है कि गेब्रियल सिल्विरा ने इस तरह के समारोह को क्यों लिखा लेकिन एक सरल रूप जो मेरे लिए भी काम करता है और बिना किसी कमी के:

Array.prototype.unique = function() {
  return this.filter(function(value, index, array) {
    return array.indexOf(value, index + 1) < 0;
  });
};

या कॉफीस्क्रिप्ट में:

Array.prototype.unique = ->
  this.filter( (value, index, array) ->
    array.indexOf(value, index + 1) < 0
  )

यदि आप प्रोटोटाइप ढांचे का उपयोग कर रहे हैं तो 'लूप' करने की कोई आवश्यकता नहीं है, आप http://www.prototypejs.org/api/array/uniq उपयोग इस तरह कर सकते हैं:

var a = Array.uniq();  

जो डुप्लिकेट सरणी का उत्पादन नहीं करेगा जिसमें डुप्लीकेट नहीं होंगे। मैं आपके प्रश्न के बाद अलग-अलग सरणी रिकॉर्ड गिनने के लिए एक विधि खोज रहा था

uniq ()

मैंनें इस्तेमाल किया

आकार ()

और मेरा सरल परिणाम था। पीएस क्षमा करें अगर मैं कुछ गलत टाइप किया

संपादित करें: यदि आप अपरिभाषित रिकॉर्ड से बचना चाहते हैं तो आप जोड़ना चाहेंगे

कॉम्पैक्ट ()

इससे पहले, इस तरह:

var a = Array.compact().uniq();  

यह काम करेगा।

function getUnique(a) {
  var b = [a[0]], i, j, tmp;
  for (i = 1; i < a.length; i++) {
    tmp = 1;
    for (j = 0; j < b.length; j++) {
      if (a[i] == b[j]) {
        tmp = 0;
        break;
      }
    }
    if (tmp) {
      b.push(a[i]);
    }
  }
  return b;
}

यहां के कई उत्तर शुरुआती लोगों के लिए उपयोगी नहीं हो सकते हैं। यदि किसी सरणी को डी-डुप्ली करना मुश्किल है, तो क्या वे वास्तव में प्रोटोटाइप श्रृंखला, या यहां तक ​​कि jQuery के बारे में भी जानेंगे?

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

const cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
const uniqueCars = Array.from(new Set(cars));

Array.from सेट को वापस एक ऐरे में कनवर्ट करने के लिए उपयोगी है ताकि आपके पास सरणी के सभी अद्भुत तरीकों (सुविधाओं) तक आसानी से पहुंच हो। एक ही काम करने के अन्य तरीके भी हैं। लेकिन आपको Array.from आवश्यकता नहीं हो सकती है। क्योंकि सेट्स के लिए बहुत उपयोगी सुविधाएं हैं जैसे forEach

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

// Create a list of cars, with duplicates.
var cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
// Create a list of unique cars, to put a car in if we haven't already.
var uniqueCars = [];

// Go through each car, one at a time.
cars.forEach(function (car) {
    // The code within the following block runs only if the
    // current car does NOT exist in the uniqueCars list
    // - a.k.a. prevent duplicates
    if (uniqueCars.indexOf(car) === -1) {
        // Since we now know we haven't seen this car before,
        // copy it to the end of the uniqueCars list.
        uniqueCars.push(car);
    }
});

इसे तुरंत पुन: प्रयोज्य बनाने के लिए, इसे एक फ़ंक्शन में डालें।

function deduplicate(data) {
    if (data.length > 0) {
        var result = [];

        data.forEach(function (elem) {
            if (result.indexOf(elem) === -1) {
                result.push(elem);
            }
        });

        return result;
    }
}

तो डुप्लिकेट से छुटकारा पाने के लिए, अब हम यह करेंगे।

var uniqueCars = deduplicate(cars);

जब कार्य पूरा हो जाता है तो deduplicate(cars) हिस्सा उस चीज बन जाता है जिसे हमने परिणाम दिया।

बस इसे अपनी पसंद के किसी भी सरणी का नाम पास करें।


सरल विधि में अद्वितीय ऐरे मान ढूँढना

function arrUnique(a){
  var t = [];
  for(var x = 0; x < a.length; x++){
    if(t.indexOf(a[x]) == -1)t.push(a[x]);
  }
  return t;
}
arrUnique([1,4,2,7,1,5,9,2,4,7,2]) // [1, 4, 2, 7, 5, 9]

http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/ (ओ (2 एन) समय जटिलता):

Array.prototype.unique = function() {
    var o = {}, i, l = this.length, r = [];
    for(i=0; i<l;i+=1) o[this[i]] = this[i];
    for(i in o) r.push(o[i]);
    return r;
};

पॉल आयरिश के ब्लॉग से : JQuery .unique() पर सुधार:

(function($){

    var _old = $.unique;

    $.unique = function(arr){

        // do the default behavior only if we got an array of elements
        if (!!arr[0].nodeType){
            return _old.apply(this,arguments);
        } else {
            // reduce the array to contain no dupes via grep/inArray
            return $.grep(arr,function(v,k){
                return $.inArray(v,arr) === k;
            });
        }
    };
})(jQuery);

// in use..
var arr = ['first',7,true,2,7,true,'last','last'];
$.unique(arr); // ["first", 7, true, 2, "last"]

var arr = [1,2,3,4,5,4,3,2,1];
$.unique(arr); // [1, 2, 3, 4, 5]

जावास्क्रिप्ट 1.6 / ईसीएमएस्क्रिप्ट 5 के साथ आप अद्वितीय मानों के साथ सरणी प्राप्त करने के लिए निम्न तरीके से एक ऐरे के मूल filter विधि का उपयोग कर सकते हैं:

function onlyUnique(value, index, self) { 
    return self.indexOf(value) === index;
}

// usage example:
var a = ['a', 1, 'a', 2, '1'];
var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']

देशी विधि filter सरणी के माध्यम से लूप होगा और केवल उन प्रविष्टियों को छोड़ देगा जो दिए गए कॉलबैक फ़ंक्शन को केवल onlyUnique पास करते हैं।

onlyUnique जांच, यदि दिया गया मान पहली बार होता है। यदि नहीं, तो यह एक डुप्लिकेट होना चाहिए और इसकी प्रतिलिपि नहीं बनाई जाएगी।

यह समाधान jQuery या prototype.js जैसी किसी अतिरिक्त लाइब्रेरी के बिना काम करता है।

यह मिश्रित मूल्य प्रकारों के साथ सरणी के लिए भी काम करता है।

पुराने ब्राउज़रों (<यानी 9) के लिए, जो मूल विधियों filter और indexOf समर्थन नहीं करते हैं, अगर आप filter और indexOf लिए एमडीएन दस्तावेज में काम आसपास के आसपास मिल सकते हैं।

यदि आप किसी मूल्य की अंतिम घटना को रखना चाहते हैं, तो indexOf द्वारा indexOf को सरल lastIndexOf

ईएस 6 के साथ इसे कम किया जा सकता है:

// usage example:
var myArray = ['a', 1, 'a', 2, '1'];
var unique = myArray.filter((v, i, a) => a.indexOf(v) === i); 

// unique is ['a', 1, 2, '1']

टिप्पणी में संकेत के लिए कैमिलो मार्टिन के लिए धन्यवाद।

ईएस 6 में एक मूल वस्तु है जो अद्वितीय मूल्यों को स्टोर करने के लिए Set है। अद्वितीय मूल्यों के साथ एक सरणी प्राप्त करने के लिए आप अब यह कर सकते हैं:

var myArray = ['a', 1, 'a', 2, '1'];

let unique = [...new Set(myArray)]; 

// unique is ['a', 1, 2, '1']

Set का कन्स्ट्रक्टर एक पुनरावृत्त ऑब्जेक्ट लेता है, जैसे ऐरे, और स्प्रेड ऑपरेटर ... सेट को वापस ऐरे में बदल देता है। टिप्पणी में संकेत के लिए लुकास Liese के लिए धन्यवाद।


केवल प्रदर्शन! यह कोड यहां सभी कोडों की तुलना में शायद 10X तेज है * सभी ब्राउज़रों पर काम करता है और इसमें सबसे कम स्मृति प्रभाव भी है .... और अधिक

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

var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];

तो आप इसे आजमा सकते हैं

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 1];

function toUnique(a, b, c) { //array,placeholder,placeholder
  b = a.length;
  while (c = --b)
    while (c--) a[b] !== a[c] || a.splice(c, 1);
  return a // not needed ;)
}
console.log(toUnique(array));
//[3, 4, 5, 6, 7, 8, 9, 0, 2, 1]

मैं इस लेख को पढ़ने के साथ इस लेख के साथ आया ...

http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/

मुझे लूप के लिए पसंद नहीं है। इसमें कई पैरामीटर हैं। मैं थोड़ी देर की तरह - लूप। जबकि सभी ब्राउज़रों में सबसे तेज़ लूप है, हम सभी को इतना पसंद है ... क्रोम।

वैसे भी मैंने पहला फ़ंक्शन लिखा जो उपयोग करता है। और हाँ, यह आलेख में मिले फ़ंक्शन से थोड़ा तेज़ है। लेकिन पर्याप्त नहीं है। unique2()

अगले कदम आधुनिक जेएस का उपयोग करें। Object.keys मैंने दूसरे को js1.7 के ऑब्जेक्ट.कीज़ के साथ लूप के लिए बदल दिया ... थोड़ा तेज़ और छोटा (क्रोम 2x तेज में);)। पर्याप्त नहीं!। unique3()

इस बिंदु पर मैं सोच रहा था कि मुझे अपने अद्वितीय कार्य में वास्तव में क्या चाहिए। मुझे पुरानी सरणी की आवश्यकता नहीं है, मुझे एक तेज कार्य चाहिए। इसलिए मैंने लूप + स्प्लिस के दौरान 2 का इस्तेमाल किया। unique4()

कहने के लिए बेकार है कि मैं प्रभावित था।

क्रोम: प्रति सेकेंड सामान्य 150,000 ऑपरेशन प्रति सेकेंड 1,800,000 ऑपरेशन तक पहुंच गए।

यानी: 80,000 सेशन / एस बनाम 3,500,000 ओप / एस

आईओएस: 18,000 ओप / एस बनाम 170,000 सेशन / एस

सफारी: 80,000 सेशन / एस बनाम 6,000,000 ओप / एस

सबूत http://jsperf.com/wgu या बेहतर कंसोल.टाइम का उपयोग करें ... microtime ... जो भी हो

unique5() यह दिखाने के लिए है कि क्या होता है यदि आप पुरानी सरणी रखना चाहते हैं।

यदि आप नहीं जानते कि आप क्या कर रहे हैं तो Array.prototype उपयोग न करें। मैंने अभी कॉपी और अतीत की बहुत कुछ किया है। Object.defineProperty(Array.prototype,...,writable:false,enumerable:false}) यदि आप मूल प्रोटोटाइप बनाना चाहते हैं। Object.defineProperty(Array.prototype,...,writable:false,enumerable:false}) : https://.com/a/20463021/2450730

डेमो http://jsfiddle.net/46S7g/

नोट: इस ऑपरेशन के बाद आपकी पुरानी सरणी नष्ट हो गई है / becomestheunique है।

अगर आप ऊपर दिए गए कोड को नहीं पढ़ सकते हैं, तो जावास्क्रिप्ट पुस्तक पढ़ें या यहां छोटे कोड के बारे में कुछ व्याख्याएं दी गई हैं। https://.com/a/21353032/2450730

कुछ indexOf का उपयोग कर रहे हैं ... नहीं ... http://jsperf.com/dgfgghfghfghghgfhgfhfghfhgfh

खाली सरणी के लिए

!array.length||toUnique(array); 

Building on other answers, here's another variant that takes an optional flag to choose a strategy (keep first occurrence or keep last):

Without extending Array.prototype

function unique(arr, keepLast) {
  return arr.filter(function (value, index, array) {
    return keepLast ? array.indexOf(value, index + 1) < 0 : array.indexOf(value) === index;
  });
};

// Usage
unique(['a', 1, 2, '1', 1, 3, 2, 6]); // -> ['a', 1, 2, '1', 3, 6]
unique(['a', 1, 2, '1', 1, 3, 2, 6], true); // -> ['a', '1', 1, 3, 2, 6]

Extending Array.prototype

Array.prototype.unique = function (keepLast) {
  return this.filter(function (value, index, array) {
    return keepLast ? array.indexOf(value, index + 1) < 0 : array.indexOf(value) === index;
  });
};

// Usage
['a', 1, 2, '1', 1, 3, 2, 6].unique(); // -> ['a', 1, 2, '1', 3, 6]
['a', 1, 2, '1', 1, 3, 2, 6].unique(true); // -> ['a', '1', 1, 3, 2, 6]

Using object keys to make unique array, I have tried following

function uniqueArray( ar ) {
  var j = {};

  ar.forEach( function(v) {
    j[v+ '::' + typeof v] = v;
  });


  return Object.keys(j).map(function(v){
    return j[v];
  });
}   

uniqueArray(["1",1,2,3,4,1,"foo", false, false, null,1]);

Which returns ["1", 1, 2, 3, 4, "foo", false, null]


Array.prototype.getUnique = function() {
    var o = {}, a = []
    for (var i = 0; i < this.length; i++) o[this[i]] = 1
    for (var e in o) a.push(e)
    return a
}





unique