জাভাস্ক্রিপ্টের জন্য অ্যান্ডস্কোর দিয়ে সদৃশ বস্তুগুলি সরানো


124

আমার এ ধরণের অ্যারে রয়েছে:

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

আমি এটি ফিল্টার করতে চাই:

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

আমি _ ইউনিক ব্যবহার করার চেষ্টা করেছি, তবে আমার ধারণা, কারণ { "a" : "1" }এটি নিজের সমান নয়, এটি কার্যকর হয় না। ওভাররাইডেন সমান ফাংশন সহ আন্ডারস্কোর ইউনিক সরবরাহ করার কোনও উপায় আছে কি?


দয়া করে আপনার
কোডটিও

জিনিসের কি { "a" : "2" }অস্তিত্ব আছে? যদি তাই হয় তবে এটি বৈশিষ্ট্য বা মান যা এটি অনন্য করে তোলে?
ম্যাট

হ্যাঁ, কী হিসাবে আমার কোনও বৈশিষ্ট্য রয়েছে, আমি সূচকটি প্রয়োগ করেছিলাম যে কেউ আমাকে অন্য বিষয়ে দেখিয়েছিল, তবে তারপরে আমি কিছু সাধারণ লাইব্রেরি ব্যবহার করে আমার কোড সাফ করতে চেয়েছিলাম
প্লাস-

1
প্লাই পরিবর্তন উত্তর গৃহীত।
ভাদোরোয়েস্ট

উত্তর:


232

.uniq / .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. লড্যাশ ডট কম ব্যবহার দেখায়

আরেকটি উদাহরণ: গাড়ি তালিকা তৈরি করতে কলব্যাক ব্যবহার করা, একটি তালিকা থেকে রঙ


falseজন্য প্রয়োজন হয় না _.uniq()। এছাড়াও লোডাসে আপনি এটি এটি লিখতে পারেন _.uniq(a, 'a');, যেহেতু এটি aবস্তুগুলির উপর সম্পত্তি হ্রাস করবে ।
ল্যারি ব্যাটেল

"'_.প্লাক' কলব্যাক শর্টহ্যান্ড" কেবল তখনই কাজ করে যদি আপনি আইসোর্টের জন্য কোনও মান পাস করেন (উদাঃ _.uniq(a, false, 'a')) আমি গিথুব / বেস্টিজ / লোডাশ পিন করেছিলাম এবং তারা বলেছিল যে বিষয়টি প্রান্তে স্থির হয়েছে। সুতরাং আপনি যদি কোনও ফাংশন ব্যবহার না করে থাকেন তবে নিশ্চিত হয়ে নিন যে আপনার কাছে সর্বশেষতম রয়েছে। এটি আন্ডারস্কোরের জন্য কোনও সমস্যা নাও হতে পারে।
শানিমাল

2
Iterator ভাল নামের মত শোনাচ্ছে না, এটি হ্যাশ মত ফাংশন যা প্রতিটি বস্তুর পরিচয় নির্ধারণ করতে হবে
জুয়ান মেন্ডেস

লোডাশ ডক্সের সাথে আরও সামঞ্জস্যপূর্ণ হতে কলব্যাক ব্যবহার করতে সম্পাদিত :)
শানিমাল

1
Jsbin এ আপনার উদাহরণ থাকতে পারে। (1) তোলে: _ (গাড়ি)। ইউনিক ('মেক')। মানচিত্র ('মেক')। মান (ও) (এবং) (2) রঙ: _ (গাড়ি) .উনিক ('রঙ')। মানচিত্র ('রঙ') ).মান(). আপনি রঙটি পাকা এবং বন্ধ করতে পারেন। (যদি আপনি ডি লোডাশ ব্যবহৃত ব্যবহৃত হয় তবে এটি আপগ্রেড)
ভিজিটর টাইবার্সকি

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" } ]

বিটিডব্লিউ, আপনি কীভাবে 4 টি আপগেট পেয়েছেন? আপনার ফলাফলের বৈশিষ্ট্যগুলি পেতে আপনাকে প্রতিটি অ্যারের মানটিকে কোনও অবজেক্টে ফিরে যেতে হবে। এর মতো কিছু JSON.parse(x[0]).aকারণ এক্স বস্তুর অ্যারে নয় এটি স্ট্রিংগুলির একটি অ্যারে। এছাড়াও, আপনি যদি বিগুলগুলিতে বি মানগুলি যুক্ত করেন এবং একটি / বিয়ের ক্রমটি উল্টান তবে সেগুলি আপনার ক্রিয়াকলাপ দ্বারা আর অনন্য হিসাবে বিবেচিত হবে না। (যেমন `" {\ "a \": \ "1 \", \ "বি \": 2} "! =" {\ "বি \": 2, \ "এ \": 1 "1 \"} ") সম্ভবত আমি কিছু মিস করছি, তবে ফলাফলটি কি কমপক্ষে কার্যকর হওয়া উচিত নয়? Jsbin.com/utoruz/2/edit
শানিমাল

1
আপনি একই কী থাকার শর্তটি সঠিক কিন্তু ভিন্ন ক্রমে প্রয়োগটি বিরতি দেয়। তবে আমি নিশ্চিত না কেন আপনি কেবল aপ্রতিটি বস্তুর জন্য কীটি পরীক্ষা করছেন , যখন কীটি নেই এমন নকল বস্তু থাকতে পারে a। যাইহোক, এটি aকোনও অনন্য আইডি হলে তা বোঝা যাবে ।
ল্যারি ব্যাটেল

আমি যখন প্রশ্নের উত্তর দিচ্ছিলাম তখন আমার কাছে মনে হয়েছিল যে প্রশ্নের ফোকাসটি ওভাররাইড করা (a ==(=) b when a = b = {a:1})। আমার উত্তরের বিষয়টি হ'ল পুনরুক্তিকারী। আমি উদ্দেশ্য সম্পর্কে চিন্তা না করে উত্তর দেওয়ার চেষ্টা করেছি, যা কিছু হতে পারে, তাই না? (যেমন: তারা কোনও শোতে গাড়ির তালিকা থেকে মেক , রঙের একটি তালিকা বের করতে চেয়েছিল j 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

ব্যবহার অনন্য আন্ডারস্কোর liberal এর সংক্ষিপ্ত রূপ নিম্নলিখিত আমার জন্য কাজ করে যাচ্ছে, আমি তালিকায় অনন্য উপার্জন করছি তারপর _id এর স্ট্রিং মান ফিরে _id এর ভিত্তি করে:

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এটি পরিষ্কার করার জন্য আপডেট হয়েছে er


একটি পূর্বনির্ধারিত অনন্য সম্পত্তি থাকার উপর নির্ভর করে না? আমি এটা পছন্দ করি.
ডন ম্যাককার্দি

1
একটি ছোট অ্যারে অবজেক্টের জন্য ভাল সমাধান তবে ইউনিক আইডি সরবরাহের তুলনায় একটি লুপের মধ্যে একটি লুপ ব্যয়বহুল।
পেনার 4


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]; });
alচ্ছিক

3

এখানে আমার সমাধান (coffeescript):

_.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

সঙ্গে আন্ডারস্কোর আমি ব্যবহার করতে হয়েছে স্ট্রিং () মধ্যে iteratee ফাংশন

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
স্ট্যাকওভারফ্লোতে স্বাগতম। আপনি যে কোড সরবরাহ করেছেন সেগুলি ছাড়াও কেন এবং কীভাবে এটি সমস্যার সমাধান করে সে সম্পর্কে কিছু ব্যাখ্যা দেওয়ার চেষ্টা করুন।
jtate

ভাল কল. ধন্যবাদ। এটি কীভাবে কাজ করে তার একটি ব্রেকডাউন সহ আপডেট হয়েছে।
কেলি বিগলি

-5

আপনি এটি সংক্ষিপ্তভাবে করতে পারেন:

_.uniq(foo, 'a')


আপনার সমাধান বস্তুর অ্যারেগুলির জন্য কাজ করে না, তবে কেবল অ্যারেগুলির জন্য
টুচুলিউর
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.