जावास्क्रिप्ट के लिए अंडरस्कोर के साथ नकली वस्तुओं को हटाना


124

मेरे पास इस तरह की सरणी है:

var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];

मैं इसे फ़िल्टर करना चाहूंगा:

var bar = [ { "a" : "1" }, { "b" : "2" }];

मैंने _.unq का उपयोग करने की कोशिश की, लेकिन मुझे लगता है क्योंकि { "a" : "1" }यह खुद के बराबर नहीं है, यह काम नहीं करता है। वहाँ एक अधिवृक्क बराबर समारोह के साथ अंडरस्कोर uniq प्रदान करने के लिए कोई रास्ता नहीं है?


कृपया अपना कोड भी पोस्ट करें
Chetter Hummin

क्या चीजें { "a" : "2" }मौजूद हैं? यदि ऐसा है तो क्या यह विशेषता या मूल्य है जो इसे अद्वितीय बनाता है?
मैट

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

1
हल परिवर्तन स्वीकार किए जाते हैं उत्तर।
वडकोरक्वेस्ट

जवाबों:


232

.unq / .unique एक कॉलबैक स्वीकार करता है

var list = [{a:1,b:5},{a:1,c:5},{a:2},{a:3},{a:4},{a:3},{a:2}];

var uniqueList = _.uniq(list, function(item, key, a) { 
    return item.a;
});

// uniqueList = [Object {a=1, b=5}, Object {a=2}, Object {a=3}, Object {a=4}]

टिप्पणियाँ:

  1. तुलना के लिए इस्तेमाल किया गया कॉलबैक रिटर्न वैल्यू
  2. अद्वितीय के रूप में उपयोग किए जाने वाले अद्वितीय वापसी मूल्य के साथ पहली तुलना वस्तु
  3. underscorejs.org बिना कॉलबैक उपयोग प्रदर्शित करता है
  4. lodash.com उपयोग दिखाता है

एक और उदाहरण: कार बनाने के लिए कॉलबैक का उपयोग करके, एक सूची से रंग


falseके लिए आवश्यक नहीं है _.uniq()। इसके अलावा, आप इसे इस तरह से लिख सकते हैं _.uniq(a, 'a');, क्योंकि यह aवस्तुओं पर संपत्ति को गिरा देगा ।
लैरी बैटल

"_.Pluck 'कॉलबैक शॉर्टहैंड" केवल तभी काम करता है जब आप isSorted (जैसे _.uniq(a, false, 'a')) के लिए मान पास करते हैं, मैंने github / bestiejs / lodash को पिंग किया और उन्होंने कहा कि मुद्दा किनारे पर तय किया गया था। इसलिए यदि आप एक फ़ंक्शन का उपयोग नहीं कर रहे हैं, तो सुनिश्चित करें कि आपके पास नवीनतम है। यह अंडरस्कोर के लिए एक मुद्दा नहीं हो सकता है।
शनीमल

2
Iterator एक अच्छे नाम की तरह आवाज नहीं करता है, यह एक हैश फ़ंक्शन की तरह है जो प्रत्येक वस्तु की पहचान निर्धारित करने के लिए होगा
जुआन मेंडेस

लॉबैक डॉक्स के साथ अधिक सुसंगत होने के लिए कॉलबैक का उपयोग करने का संपादन किया गया :)
शनीमल

1
आप उदाहरण के लिए jsbin में एक अद्यतन हो सकता है। : )।का मूल्य()। आप रंग को बंद कर सकते हैं और बंद कर सकते हैं। (यदि आप डे लॉश को अपग्रेड करते हैं तो सभी)
विटर टाइबर्स्की

38

यदि आप एक आईडी के आधार पर डुप्लिकेट को हटाने के लिए देख रहे हैं तो आप कुछ ऐसा कर सकते हैं:

var res = [
  {id: 1, content: 'heeey'},
  {id: 2, content: 'woah'}, 
  {id: 1, content:'foo'},
  {id: 1, content: 'heeey'},
];
var uniques = _.map(_.groupBy(res,function(doc){
  return doc.id;
}),function(grouped){
  return grouped[0];
});

//uniques
//[{id: 1, content: 'heeey'},{id: 2, content: 'woah'}]

अद्वितीय पहचानकर्ता के होने पर स्वीकृत उत्तर काम नहीं करता है Date। हालाँकि यह करता है।
गनविन

17

शिप्लू के उत्तर का कार्यान्वयन।

var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];

var x = _.uniq( _.collect( foo, function( x ){
    return JSON.stringify( x );
}));

console.log( x ); // returns [ { "a" : "1" }, { "b" : "2" } ]

btw, आपको 4 अपवोट कैसे मिले? अपने परिणाम के गुणों को प्राप्त करने के लिए आपको प्रत्येक सरणी मान को किसी ऑब्जेक्ट में वापस करना होगा। कुछ ऐसा है JSON.parse(x[0]).aक्योंकि x वस्तुओं का एक सरणी नहीं है, यह तारों का एक सरणी है। इसके अलावा, यदि आप un मानों में b मान जोड़ते हैं और a / b के क्रम को उल्टा करते हैं तो वे आपके फ़ंक्शन द्वारा अद्वितीय नहीं माने जाते हैं। (उदाहरण के लिए "" {\ "a \": \ "1 \", \ "b \": 2} "!" = "{\" b \ ": 2, \" a \ ": \" 1 \ "} ") शायद कुछ याद आ रही है, लेकिन परिणाम कम से कम उपयोगी नहीं होना चाहिए? यहाँ jsbin.com/utoruz/2/edit
Shanimal

1
आप एक ही कुंजी होने की शर्त सही हैं, लेकिन अलग-अलग क्रम में कार्यान्वयन को तोड़ते हैं। लेकिन मैं अनिश्चित हूं कि आप केवल aप्रत्येक ऑब्जेक्ट के लिए कुंजी की जांच कर रहे हैं , जब डुप्लिकेट ऑब्जेक्ट हो सकते हैं जिसमें कुंजी नहीं थी a। हालांकि, यह aएक अद्वितीय आईडी था अगर यह समझ में आता है ।
लैरी बैटल

जब मैं इस सवाल का जवाब दे रहा था तो मुझे लगा कि सवाल का फोकस ओवरराइड करना है (a ==(=) b when a = b = {a:1})। मेरे उत्तर का बिंदु पुनरावृत्त था। मैंने मकसद के बारे में चिंता किए बिना जवाब देने की कोशिश की, जो कुछ भी हो सकता है, है ना? (उदाहरण के लिए शायद वे शो में कारों की सूची से मेक , कलर्स की एक सूची निकालना चाहते थे। jsbin.com/evodub/2/edit ) चीयर्स!
शनीमल

इसके अलावा, मुझे लगता है कि यह हमें संक्षिप्त जवाब देने में मदद करता है जब कोई प्रश्न पूछ रहा है तो मकसद प्रदान करता है। यह एक दौड़ है, इसलिए मैं पहले होना पसंद करता हूं और यदि आवश्यक हो तो स्पष्ट करता हूं। संत पत्रिक डे की शुभकामनाये।
शनीमल

वैसे मैंने सिर्फ एक और अपवोट दिया क्योंकि इससे नेस्टेड एरेज़ की तुलना करने पर मेरे सवाल का जवाब मिला। केवल कैसे ओवरराइड करने के लिए के लिए देख रहा थाiterator
nevi_me

15

जब मेरे पास एक विशेषता आईडी होती है, तो यह अंडरस्कोर में मेरा प्रचलित तरीका है:

var x = [{i:2}, {i:2, x:42}, {i:4}, {i:3}];
_.chain(x).indexBy("i").values().value();
// > [{i:2, x:42}, {i:4}, {i:3}]

12

अंडरस्कोर यूनिक लाइब का उपयोग करना मेरे लिए काम कर रहा है, मैं मी के आधार पर सूची को अद्वितीय बना रहा हूं, फिर _ के स्ट्रिंग मान को लौटाता हूं:

var uniqueEntities = _.uniq(entities, function (item, key, a) {
                                    return item._id.toString();
                                });

10

यहाँ एक सरल उपाय है, जो डुप्लिकेट के लिए जाँच करने के लिए एक गहरी वस्तु की तुलना का उपयोग करता है (बिना JSON में कनवर्ट करने के लिए, जो अक्षम और हैकी है)

var newArr = _.filter(oldArr, function (element, index) {
    // tests if the element has a duplicate in the rest of the array
    for(index += 1; index < oldArr.length; index += 1) {
        if (_.isEqual(element, oldArr[index])) {
            return false;
        }
    }
    return true;
});

यह सभी तत्वों को फ़िल्टर करता है यदि उनके पास सरणी में बाद में एक डुप्लिकेट है - जैसे कि अंतिम डुप्लिकेट तत्व रखा गया है।

डुप्लिकेट उपयोगों के लिए परीक्षण, _.isEqualजो दो वस्तुओं के बीच एक अनुकूलित गहरी तुलना करता है , अधिक जानकारी के लिए अंडरस्कोर प्रलेखन को देखता है

संपादित करें: उपयोग करने के लिए अद्यतन _.filterजो एक क्लीनर दृष्टिकोण है


एक पूर्वनिर्धारित अद्वितीय संपत्ति होने पर निर्भर नहीं करता है? मुझें यह पसंद है।
डॉन मैककरी

1
वस्तुओं के एक छोटे से सरणी के लिए एक अच्छा समाधान लेकिन एक लूप के भीतर एक लूप एक यूनीक आईडी प्रदान करने की तुलना में महंगा है।
पेनर


7

पुनरावृत्त समारोह की कोशिश करो

उदाहरण के लिए आप पहले तत्व को वापस कर सकते हैं

x = [['a',1],['b',2],['a',1]]

_.uniq(x,false,function(i){  

   return i[0]   //'a','b'

})

=> [['ए', १], ['बी', २]]


सेकंड तर्क वास्तव में वैकल्पिक है, आप यह भी कर सकते हैं_.uniq(x,function(i){ return i[0]; });
jakecraige

3

यहाँ मेरा समाधान (कॉफ़ीस्क्रिप्ट) है:

_.mixin
  deepUniq: (coll) ->
    result = []
    remove_first_el_duplicates = (coll2) ->

      rest = _.rest(coll2)
      first = _.first(coll2)
      result.push first
      equalsFirst = (el) -> _.isEqual(el,first)

      newColl = _.reject rest, equalsFirst

      unless _.isEmpty newColl
        remove_first_el_duplicates newColl

    remove_first_el_duplicates(coll)
    result

उदाहरण:

_.deepUniq([ {a:1,b:12}, [ 2, 1, 2, 1 ], [ 1, 2, 1, 2 ],[ 2, 1, 2, 1 ], {a:1,b:12} ]) 
//=> [ { a: 1, b: 12 }, [ 2, 1, 2, 1 ], [ 1, 2, 1, 2 ] ]

3

अंडरस्कोर के साथ मुझे स्ट्रिंग () को इटर्सेट फ़ंक्शन में उपयोग करना था

function isUniq(item) {
    return String(item.user);
}
var myUniqArray = _.uniq(myArray, isUniq);

0

मैं लेखन के सीधे तरीके से इस सरल समाधान को हल करना चाहता था, कम्प्यूटेशनल खर्चों का थोड़ा सा दर्द के साथ ... लेकिन क्या यह न्यूनतम चर परिभाषा के साथ एक तुच्छ समाधान नहीं है, है ना?

function uniq(ArrayObjects){
  var out = []
  ArrayObjects.map(obj => {
    if(_.every(out, outobj => !_.isEqual(obj, outobj))) out.push(obj)
  })
  return out
}

0
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var bar = _.map(_.groupBy(foo, function (f) { 
        return JSON.stringify(f); 
    }), function (gr) { 
        return gr[0]; 
    }
);

इससे टूट जाते हैं। पहले समूह आइटमों को उनके कठोर मान द्वारा समूहित करने देता है

var grouped = _.groupBy(foo, function (f) { 
    return JSON.stringify(f); 
});

grouped की तरह लगता है:

{
    '{ "a" : "1" }' = [ { "a" : "1" } { "a" : "1" } ],
    '{ "b" : "2" }' = [ { "b" : "2" } ]
}

फिर प्रत्येक समूह से पहला तत्व हड़पने देता है

var bar = _.map(grouped, function(gr)
    return gr[0]; 
});

bar की तरह लगता है: [ { "a" : "1" }, { "b" : "2" } ]

इसे एक साथ रखें:

var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var bar = _.map(_.groupBy(foo, function (f) { 
        return JSON.stringify(f); 
    }), function (gr) { 
        return gr[0]; 
    }
);

3
Stackoverflow में आपका स्वागत है। आपके द्वारा प्रदान किए गए कोड के अलावा, यह क्यों और कैसे इस समस्या को हल करता है पर कुछ स्पष्टीकरण देने का प्रयास करें।
18

अच्छा निर्णय। धन्यवाद। यह कैसे काम करता है, इसके टूटने के साथ अद्यतन किया गया।
केली बिगले

-5

आप इसे आशुलिपि में कर सकते हैं:

_.uniq(foo, 'a')


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