জাভাস্ক্রিপ্টে দুটি অ্যারের মধ্যে পার্থক্য কীভাবে পাবেন?


751

জাভাস্ক্রিপ্টে দুটি অ্যারের মধ্যে পার্থক্য ফেরানোর কোনও উপায় আছে কি?

উদাহরণ স্বরূপ:

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

// need ["c", "d"]

9
প্রতিসম বা নন-প্রতিসম?
অরবিট-

নতুন ES6 ফাংশন সহ এটি একটি সাধারণ একটি লাইনার হিসাবে করা যেতে পারে (সমস্ত বড় ব্রাউজারগুলিতে এটি ব্যবহার করতে সক্ষম হতে অনেক বেশি সময় লাগবে)। যাই হোক না কেন আমার উত্তরটি দেখুন
সালভাদোর ডালি

1
সমাধানের একটি গুরুত্বপূর্ণ বিষয় হল কর্মক্ষমতা। অন্যান্য ধরণের ভাষায় - এই ধরণের অপারেশনের অ্যাসিম্পটোটিক টাইম জটিলতা O(a1.length x log(a2.length))কি জাভাস্ক্রিপ্টে এই সম্পাদন সম্ভব?
রাউল

উত্তর:


218

আমি ধরে নিয়েছি আপনি একটি সাধারণ অ্যারের তুলনা করছেন। যদি না, আপনি পরিবর্তন করতে হবে জন্য লুপ একটি থেকে এ .. জন্য লুপ।

function arr_diff (a1, a2) {

    var a = [], diff = [];

    for (var i = 0; i < a1.length; i++) {
        a[a1[i]] = true;
    }

    for (var i = 0; i < a2.length; i++) {
        if (a[a2[i]]) {
            delete a[a2[i]];
        } else {
            a[a2[i]] = true;
        }
    }

    for (var k in a) {
        diff.push(k);
    }

    return diff;
}

console.log(arr_diff(['a', 'b'], ['a', 'b', 'c', 'd']));
console.log(arr_diff("abcd", "abcde"));
console.log(arr_diff("zxc", "zxc"));

আরও ভাল সমাধান, যদি আপনি পশ্চাদপটে সামঞ্জস্যতা সম্পর্কে চিন্তা না করেন তবে ফিল্টারটি ব্যবহার করছেন। কিন্তু এখনও, এই সমাধান কাজ করে।


46
এটি কাজ করতে পারে তবে অ্যারের ফিল্টার পদ্ধতিটি ব্যবহার করে কোডের এক লাইনে কী করা যায় তা সম্পাদন করতে এটি তিনটি লুপ করে।
জোশাভেন পটার

9
শুধু থেকে পরিষ্কার হতে, এই কার্যকরী প্রতিসম পার্থক্য এর A1 এবং A2 , অন্যান্য উত্তর অসদৃশ এখানে পোস্ট।
200_সাক্সেস

25
এটি সর্বোত্তম উত্তর নয়, তবে আমি অন্যায় সুবিধাবঞ্চিতদের জন্য সহায়তা করার জন্য এটি একটি চ্যারিটি আপভোট দিচ্ছি। কেবলমাত্র ভুল উত্তরগুলি হ্রাস করা উচিত, এবং যদি আমি ক্রপ-ব্রাউজারগুলির সাথে স্কোপে (কঠিন সময় ঘটে) নিয়ে কোনও প্রকল্পে কাজ করতাম তবে এই উত্তরটি এমনকি সহায়ক হতে পারে।
মাইকেল শ্যাপার

3
আমি জানতে পারি কি ঘটবে যখন var a1 = ['a', 'b'];এবং var a2 = ['a', 'b', 'c', 'd', 'b'];, এটা ভুল উত্তর ফিরে আসবে , অর্থাত্ ['c', 'd', 'b']পরিবর্তে ['c', 'd']
skbly7

4
দ্রুততম উপায় হ'ল সবচেয়ে স্পষ্টতই নিষ্পাপ সমাধান na আমি এই থ্রেডে প্রতিসাম্যগত পার্থক্যের জন্য প্রস্তাবিত সমস্ত সমাধানের পরীক্ষা করেছি এবং বিজয়ী হ'ল:function diff2(a, b) { var i, la = a.length, lb = b.length, res = []; if (!la) return b; else if (!lb) return a; for (i = 0; i < la; i++) { if (b.indexOf(a[i]) === -1) res.push(a[i]); } for (i = 0; i < lb; i++) { if (a.indexOf(b[i]) === -1) res.push(b[i]); } return res; }
২ma

1220

ES7 ব্যবহারের আরও ভাল উপায় রয়েছে:


ছেদ

 let intersection = arr1.filter(x => arr2.includes(x));

ছেদ পার্থক্য ভেন ডায়াগ্রাম

এর জন্য [1,2,3] [2,3]ফলন হবে [2,3]। অন্যদিকে, জন্য [1,2,3] [2,3,5]একই জিনিস ফিরে আসবে।


পার্থক্য

let difference = arr1.filter(x => !arr2.includes(x));

ডান পার্থক্য ভেন ডায়াগ্রাম

এর জন্য [1,2,3] [2,3]ফলন হবে [1]। অন্যদিকে, জন্য [1,2,3] [2,3,5]একই জিনিস ফিরে আসবে।


একটি প্রতিসম পার্থক্য জন্য , আপনি এটি করতে পারেন:

let difference = arr1
                 .filter(x => !arr2.includes(x))
                 .concat(arr2.filter(x => !arr1.includes(x)));

প্রতিসম পার্থক্য ভেন ডায়াগ্রাম

এইভাবে, আপনি একটি অ্যারে পাবেন যা এরি 2 এর সমস্ত উপাদানগুলি রয়েছে যা অ্যার 2 এবং তদ্বিপরীত নয়

@ জোশাভেন পটার তার উত্তরের দিকে ইঙ্গিত করার সাথে সাথে আপনি এটিকে অ্যারে.প্রোটোটাইপে যুক্ত করতে পারেন যাতে এটি এর মতো ব্যবহার করা যায়:

Array.prototype.diff = function(arr2) { return this.filter(x => !arr2.includes(x)); }
[1, 2, 3].diff([2, 3])

3
আমি < 0পরিবর্তে চেক করতে পছন্দ করি== -1
ভিক

1
কম্পিউটিং Arrayপার্থক্য একটি তথাকথিত হয় set operation, কারণ সম্পত্তি লুকআপ খুব নিজের কাজ Setগুলি, যা দ্রুত তারপর মাত্রার আদেশ হয় indexOf/ includes। সহজ কথায় বলতে গেলে আপনার সমাধানটি খুব অদক্ষ এবং বরং ধীর।

@ ফোর কিন্তু সাথে Set, মানগুলি অনন্য হতে হবে, না?
সার্ভেড

1
@ লুইসেইইরা আমি পেয়েছি [1,2,3] [2,3,5]যে এই সংখ্যাগুলি অনন্য বলে দেওয়া হলেও এটি কার্যকর হবে তবে আপনি যদি বলেছিলেন [1,1,2,3] [1,2,3,5]এবং আশা করেছিলেন [1]আপনি ব্যবহার করতে পারবেন না Set। আপনার সমাধানটি যদিও কাজ করবে না: - / আমি এই ফাংশনটি তৈরি করে শেষ করেছি কারণ আমি এটি আরও সান্নিধ্যভাবে করার কোনও সন্তোষজনক উপায় বের করতে পারি না। এটি করার জন্য আপনার যদি কোনও ধারণা থাকে তবে আমি তা জানতে আগ্রহী!
সারভেড

3
Array.includes()ES6 এর পরিবর্তে ES7 বৈশিষ্ট্যটি কি নয় ? (1) (2) - এবং চালিয়ে যেতে ES6 এর সাহায্যে আপনি Array.some()উদাহরণস্বরূপ let intersection = aArray.filter(a => bArray.some(b => a === b)), না?
জারি কেইনেনেন

910
Array.prototype.diff = function(a) {
    return this.filter(function(i) {return a.indexOf(i) < 0;});
};

////////////////////  
// Examples  
////////////////////

[1,2,3,4,5,6].diff( [3,4,5] );  
// => [1, 2, 6]

["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);  
// => ["test5", "test6"]

নোট সূচিপত্র এবং ফিল্টার ie9 এর আগে পাওয়া যায় না।


50
ফিল্টার এবং ইন্ডেক্সঅফ সমর্থন করে না এমন একমাত্র ব্রাউজারটি আইই 8। আইই 9 তাদের উভয়কে সমর্থন করে। সুতরাং এটি ভুল নয়।
ব্রায়ান লারসন

14
ie7 এবং IE8 এখনও (দুর্ভাগ্যবশত) খুব প্রাসঙ্গিক, তবে আপনি MDN সাইটে উভয় কাজকর্মের জন্য polyfill কোড খুঁজতে পারেন: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/... developer.mozilla.org/en/JavaScript/ রেফারেন্স / গ্লোবাল_অবজেক্টস /… কোনও আইই শর্তসাপেক্ষ এবং বিওএম এর মাধ্যমে " কমপ্যাটিবিলিটি " এর অধীনে তালিকাভুক্ত কোডটিতে লোড করুন। আইই 7/8 সমর্থিত।
1nfiniti

44
এই দ্রবণটির ও (রান n 2) এর একটি রান সময় রয়েছে একটি লিনিয়ার দ্রবণটি আরও কার্যকর হবে।
jholloman

75
আপনি যদি ফাংশনটি এভাবে ব্যবহার করেন: [1,2,3].diff([3,4,5])এটি [1,2]পরিবর্তে ফিরে আসবে [1,2,4,5]তাই এটি মূল প্রশ্নে সমস্যাটি সমাধান করে না, সচেতন হওয়ার মতো কিছু।
বাগস্টার

12
@ অ্যালিনপুরকারু প্রত্নতাত্ত্বিক ব্রাউজারগুলির দ্বারা সমর্থিত নয়! = ভুল। নেটস্কেপ ২.০ বিবেচনা করে, এখানে বেশিরভাগ জেএস কোড এই সংজ্ঞা দ্বারা "ভুল"। বলার মতো নির্বোধ বিষয়।
নুল ইউজার এক্সসেপশন

304

JQuery ব্যবহার করে আপনি যে ফলাফলটি সন্ধান করছেন ঠিক তা পাওয়ার এটি এখন পর্যন্ত সবচেয়ে সহজ উপায়:

var diff = $(old_array).not(new_array).get();

diffএখন রয়েছে কি ছিল old_arrayযে নেইnew_array


4
@Batman হ্যাঁ, কিন্তু শুধুমাত্র যদি তারা রেফারেন্স একই বস্তু ( {a: 1} != {a: 1}) ( প্রমাণ )
Matmarbon

কাস্টম অবজেক্টের ডেটা ধারণ করে অ্যারে দিয়ে এটি ব্যবহার করা সম্ভব? আমি আসলে এটি একইভাবে চেষ্টা করেছি কিন্তু এটি কার্যকর হয়নি। যে কোনও ধারণা অত্যন্ত প্রশংসনীয় হবে।
লেটমেকোড ইউ

8
এটা কি কৌশল? ডক অংশ হিসেবে এই পদ্ধতি বিবেচনা করে DOM উপাদান পদ্ধতি এবং একটি সাধারণ অ্যারে সাহায্যকারী হিসাবে। সুতরাং এটি এখন এইভাবে কাজ করতে পারে তবে ভবিষ্যতের সংস্করণগুলিতে নাও হতে পারে, কারণ এটি এটিকে এভাবে ব্যবহার করার উদ্দেশ্যে করা হয়নি। যদিও, আমি আনন্দে থাকি যদি এটি আনুষ্ঠানিকভাবে একটি সাধারণ অ্যারে সহায়ক হয়।
রোবস

1
@robsch আপনি যখন .notএকটি অ্যারের সাথে ব্যবহার করেন, jQuery এটি বিল্ট-ইন ইউটিলিটি ব্যবহার করে .grep()যা বিশেষত অ্যারে ফিল্টার করার জন্য। আমি এই পরিবর্তন দেখতে পাচ্ছি না।
সুপারফোনিক

1
@vsync আপনার মতামত একটি প্রতিসাম্য পার্থক্যের পরে হয়েছে
সুপারফোনিক

158

অ্যান্ডস্কোরের পার্থক্য পদ্ধতি (বা এর ড্রপ-ইন প্রতিস্থাপন, লো-ড্যাশ ) এটিও করতে পারে:

(R)eturns the values from array that are not present in the other arrays

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]

যে কোনও ইন্ডস্কোর ফাংশনের মতো, আপনি এটি আরও বেশি অবজেক্ট-ভিত্তিক স্টাইলে ব্যবহার করতে পারেন:

_([1, 2, 3, 4, 5]).difference([5, 2, 10]);

4
আমি মনে করি এটি একটি ভাল সমাধান কর্মক্ষমতা-ভিত্তিক, বিশেষত লোড্যাশ এবং আন্ডারস্কোর সর্বোত্তম বাস্তবায়নের জন্য লড়াই চালিয়ে যাওয়ায়। এছাড়াও, এটি আই 6-সামঞ্জস্যপূর্ণ।
মাহেমফ

4
সাবধান, এই বাস্তবায়ন বস্তুর অ্যারে জন্য কাজ করবে না। আরও তথ্যের জন্য stackoverflow.com/q/8672383/14731 দেখুন ।
গিলি

1
উত্তরগুলির মধ্যে যেহেতু এখানে উল্লেখ করা হয়েছে, এটি একই জিনিস হলে এটি কাজ করে তবে দুটি বস্তুর একই বৈশিষ্ট্য থাকলে তা নয়। আমি মনে করি যে ঠিক আছে যেহেতু সাম্যতার ধারণাগুলি পরিবর্তিত হয় (উদাহরণস্বরূপ এটি কিছু অ্যাপ্লিকেশনগুলিতে "আইডি" বৈশিষ্ট্যও হতে পারে)। তবে এটি ভাল হবে যদি আপনি তুলনামূলক পরীক্ষায় পাস করতে পারেন () ect
মাহমোফ

উত্তরোত্তর জন্য: লোড্যাশের এখন _.differencesBy () রয়েছে যা তুলনা করতে কলব্যাক নেয়; আপনি যদি বস্তুর তুলনা করছেন তবে আপনি কোনও ফাংশনটিতে ফেলে দিতে পারেন যা আপনার প্রয়োজনের সাথে তুলনা করে।
সোমারকলিমটাইম

2
আর্গুমেন্টের ক্রমটি যদি বিপরীত হয় তবে সাবধানতা অবলম্বন করুন it যেমন। _. ডিফারেন্স ([5, 2, 10], [1, 2, 3, 4, 5]); পার্থক্যটি পেতে পারেন না
রাশজ

79

সরল জাভাস্ক্রিপ্ট

"পার্থক্য" এর জন্য দুটি সম্ভাব্য ব্যাখ্যা রয়েছে। আপনি যা চান তা আমি আপনাকে বেছে নিতে দেব। বলুন আপনার আছে:

var a1 = ['a', 'b'     ];
var a2 = [     'b', 'c'];
  1. আপনি যদি পেতে চান তবে ['a']এই ফাংশনটি ব্যবহার করুন:

    function difference(a1, a2) {
      var result = [];
      for (var i = 0; i < a1.length; i++) {
        if (a2.indexOf(a1[i]) === -1) {
          result.push(a1[i]);
        }
      }
      return result;
    }
  2. আপনি যদি ['a', 'c'](সমস্ত উপাদানগুলিতে থাকে a1 বা a2উভয়ই থাকে না তবে উভয়ই তথাকথিত প্রতিসম পার্থক্য ) পেতে চান তবে এই ফাংশনটি ব্যবহার করুন:

    function symmetricDifference(a1, a2) {
      var result = [];
      for (var i = 0; i < a1.length; i++) {
        if (a2.indexOf(a1[i]) === -1) {
          result.push(a1[i]);
        }
      }
      for (i = 0; i < a2.length; i++) {
        if (a1.indexOf(a2[i]) === -1) {
          result.push(a2[i]);
        }
      }
      return result;
    }

লোডাশ / ইন্ডারস্কোর

আপনি যদি লোডাশ ব্যবহার করছেন তবে আপনি _.difference(a1, a2)(উপরের কেস 1) বা _.xor(a1, a2)(কেস 2) ব্যবহার করতে পারেন ।

যদি আপনি অ্যান্ডসোর.জেএস ব্যবহার করেন তবে আপনি _.difference(a1, a2)কেস 1 এর জন্য ফাংশনটি ব্যবহার করতে পারেন ।

ES6 সেট, খুব বড় অ্যারে জন্য

উপরের কোডটি সমস্ত ব্রাউজারে কাজ করে। তবে প্রায় 10,000 টিরও বেশি আইটেমের বৃহত অ্যারেগুলির জন্য এটি বেশ ধীরে ধীরে হয়ে যায়, কারণ এতে O (n²) জটিলতা রয়েছে। অনেক আধুনিক ব্রাউজারে, আমরা Setজিনিসগুলি গতি বাড়ানোর জন্য ES6 অবজেক্টের সুবিধা নিতে পারি । লোড্যাশ Setএটি উপলভ্য হলে স্বয়ংক্রিয়ভাবে ব্যবহার করে । আপনি যদি লোডাশ ব্যবহার না করে থাকেন তবে এক্সেল রাউশমায়ারের ব্লগ পোস্টটি দ্বারা অনুপ্রাণিত নিম্নলিখিত প্রয়োগগুলি ব্যবহার করুন :

function difference(a1, a2) {
  var a2Set = new Set(a2);
  return a1.filter(function(x) { return !a2Set.has(x); });
}

function symmetricDifference(a1, a2) {
  return difference(a1, a2).concat(difference(a2, a1));
}

মন্তব্য

আপনি যদি -0, +0, NAN বা স্পারস অ্যারেগুলি যত্ন করে থাকেন তবে সমস্ত উদাহরণের আচরণটি অবাক করে বা স্পষ্ট নয় be (বেশিরভাগ ব্যবহারের জন্য, এটি কোনও ব্যাপার নয়)


ধন্যবাদ। তুমি আমার দিন বাঁচিয়েছ আমাকে একটি 300K অ্যারে তুলনা করতে হয়েছিল এবং আপনার "সেট" সমাধানটি পুরোপুরি কার্যকর হয়েছিল। এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
জাস্টদেব

52

প্রতিসম পার্থক্য পেতে আপনাকে উভয় উপায়ে অ্যারে তুলনা করতে হবে (বা একাধিক অ্যারের ক্ষেত্রে সমস্ত উপায়ে)

এখানে চিত্র বর্ণনা লিখুন


ES7 (ECMAScript 2016)

// diff between just two arrays:
function arrayDiff(a, b) {
    return [
        ...a.filter(x => !b.includes(x)),
        ...b.filter(x => !a.includes(x))
    ];
}

// diff between multiple arrays:
function arrayDiff(...arrays) {
    return [].concat(...arrays.map( (arr, i) => {
        const others = arrays.slice(0);
        others.splice(i, 1);
        const unique = [...new Set([].concat(...others))];
        return arr.filter(x => !unique.includes(x));
    }));
}

ES6 (ECMAScript 2015)

// diff between just two arrays:
function arrayDiff(a, b) {
    return [
        ...a.filter(x => b.indexOf(x) === -1),
        ...b.filter(x => a.indexOf(x) === -1)
    ];
}

// diff between multiple arrays:
function arrayDiff(...arrays) {
    return [].concat(...arrays.map( (arr, i) => {
        const others = arrays.slice(0);
        others.splice(i, 1);
        const unique = [...new Set([].concat(...others))];
        return arr.filter(x => unique.indexOf(x) === -1);
    }));
}

ES5 (ECMAScript 5.1)

// diff between just two arrays:
function arrayDiff(a, b) {
    var arrays = Array.prototype.slice.call(arguments);
    var diff = [];

    arrays.forEach(function(arr, i) {
        var other = i === 1 ? a : b;
        arr.forEach(function(x) {
            if (other.indexOf(x) === -1) {
                diff.push(x);
            }
        });
    })

    return diff;
}

// diff between multiple arrays:
function arrayDiff() {
    var arrays = Array.prototype.slice.call(arguments);
    var diff = [];

    arrays.forEach(function(arr, i) {
        var others = arrays.slice(0);
        others.splice(i, 1);
        var otherValues = Array.prototype.concat.apply([], others);
        var unique = otherValues.filter(function (x, j) { 
            return otherValues.indexOf(x) === j; 
        });
        diff = diff.concat(arr.filter(x => unique.indexOf(x) === -1));
    });
    return diff;
}

উদাহরণ:

// diff between two arrays:
const a = ['a', 'd', 'e'];
const b = ['a', 'b', 'c', 'd'];
arrayDiff(a, b); // (3) ["e", "b", "c"]

// diff between multiple arrays
const a = ['b', 'c', 'd', 'e', 'g'];
const b = ['a', 'b'];
const c = ['a', 'e', 'f'];
arrayDiff(a, b, c); // (4) ["c", "d", "g", "f"]

অবজেক্টের অ্যারেগুলির মধ্যে পার্থক্য

function arrayDiffByKey(key, ...arrays) {
    return [].concat(...arrays.map( (arr, i) => {
        const others = arrays.slice(0);
        others.splice(i, 1);
        const unique = [...new Set([].concat(...others))];
        return arr.filter( x =>
            !unique.some(y => x[key] === y[key])
        );
    }));
}

উদাহরণ:

const a = [{k:1}, {k:2}, {k:3}];
const b = [{k:1}, {k:4}, {k:5}, {k:6}];
const c = [{k:3}, {k:5}, {k:7}];
arrayDiffByKey('k', a, b, c); // (4) [{k:2}, {k:4}, {k:6}, {k:7}]

49

ES6 এর একটি ক্লিনার পদ্ধতির নিম্নলিখিত সমাধান।

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

পার্থক্য

a2.filter(d => !a1.includes(d)) // gives ["c", "d"]

ছেদ

a2.filter(d => a1.includes(d)) // gives ["a", "b"]

বিচ্ছিন্ন ইউনিয়ন (প্রতিসম পার্থক্য)

[ ...a2.filter(d => !a1.includes(d)),
  ...a1.filter(d => !a2.includes(d)) ]

এটি কেবল এক দিকে কাজ করে। এখন কল্পনা করুন a1 = ['a', 'b', 'e']: ই তোলা হবে না।
imrok

হ্যাঁ, সেট থিওরিতে পার্থক্য এইভাবে কাজ করে। (a2 -a1) আপনি যা খুঁজছেন তা হ'ল (a2-a1) + (a1-a2)
ifelse.codes

1
@ আইম্রোক আমি বিশ্বাস করি এটিই আপনি খুঁজছেন [... a2.filter (d =>! a1.includes (d)), ... (a1.filter (d =>! a2.includes (d)) )]
ifelse.codes

2
সুন্দর সমাধান, ধন্যবাদ!
থিয়াগো আলভেস

40

আপনি এই ক্ষেত্রে একটি সেট ব্যবহার করতে পারেন । এটি এই ধরণের অপারেশনের (ইউনিয়ন, ছেদ, পার্থক্য) জন্য অনুকূলিত।

একবার এটি কোনও নকলকে মঞ্জুরি দেয় না তা নিশ্চিত হয়ে নিন এটি আপনার ক্ষেত্রে প্রযোজ্য।

var a = new JS.Set([1,2,3,4,5,6,7,8,9]);
var b = new JS.Set([2,4,6,8]);

a.difference(b)
// -> Set{1,3,5,7,9}

4
দেখতে সুন্দর লাইব্রেরির মতো! কী লজ্জাজনক যে আপনি সমস্ত কিছু না Setপেয়ে আপনি কেবল ফাংশনটি ডাউনলোড করতে পারবেন না ...
Blixt

@ ব্লিক্স্ট আমি বিশ্বাস করি আপনি এটি সব ডাউনলোড করতে পারেন, এবং কেবল সেট.জেএস ফাইল অন্তর্ভুক্ত করুন
স্যামুয়েল ক্যারিজো

গুগল ক্লোজারেও সেট সেট প্রয়োগ করা হয়েছে। বন্ধ-library.googlecode.com/svn/docs/…
বেন ফ্লিন

1
বাহ, এক বছর হয়ে গেল? বিকাশকারী.মোজিলা.আর.ইন-
ইউএস

32
function diff(a1, a2) {
  return a1.concat(a2).filter(function(val, index, arr){
    return arr.indexOf(val) === arr.lastIndexOf(val);
  });
}

উভয় অ্যারে মার্জ করুন, অনন্য মানগুলি কেবল একবার উপস্থিত হবে তাই সূচিপত্রফ () সর্বশেষআইডেক্সফ () হিসাবে একই হবে।


3
আমি সম্মত হলাম এটি সবচেয়ে পরিষ্কার এবং সহজ উপায় এবং দুর্দান্ত যে এটির জন্য স্পর্শকৃত প্রোটোটাইপের প্রয়োজন নেই। "আপনি যদি এটি ছয় বছরের পুরোনোকে ব্যাখ্যা করতে না পারেন, তবে আপনি নিজে এটি বুঝতে পারেন না।" - অ্যালবার্ট আইনস্টাইন
lacostenycoder

18

অন্য থেকে একটি অ্যারে বিয়োগ করতে, কেবল নীচের স্নিপেট ব্যবহার করুন:

var a1 = ['1','2','3','4','6'];
var a2 = ['3','4','5'];

var items = new Array();

items = jQuery.grep(a1,function (item) {
    return jQuery.inArray(item, a2) < 0;
});

এটি ['1,' 2 ',' 6 '] ফিরিয়ে দেবে যা প্রথম অ্যারের আইটেম যা দ্বিতীয়টিতে নেই।

সুতরাং, আপনার সমস্যার নমুনা অনুসারে, নিম্নলিখিত কোডটি হ'ল সঠিক সমাধান:

var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];

var _array = new Array();

_array = jQuery.grep(array2, function (item) {
     return jQuery.inArray(item, array1) < 0;
});

14

ES6 এর আগমন সাথে সেট এবং স্প্ল্যাট অপারেটর (শুধুমাত্র ফায়ারফক্সে কাজ করার সময়, সামঞ্জস্যতার টেবিলটি পরীক্ষা করুন ), আপনি নিম্নলিখিত একটি লাইনার লিখতে পারেন:

var a = ['a', 'b', 'c', 'd'];
var b = ['a', 'b'];
var b1 = new Set(b);
var difference = [...new Set([...a].filter(x => !b1.has(x)))];

যার ফলস্বরূপ হবে [ "c", "d" ]


শুধু কৌতূহল কীভাবে এটি করা থেকে কোনও আলাদাb.filter(x => !a.indexOf(x)))
chovy

1
@ চেভি এটি সময়ের জটিলতায় আলাদা। আমার সমাধানটি হল O(n + m)আপনার সমাধানটি O(n * m)যেখানে এন এবং এম দৈর্ঘ্যের অ্যারে হয়। দীর্ঘ তালিকাগুলি নিন এবং আমার সমাধানটি কয়েক সেকেন্ড পরে চলবে, যখন আপনার কয়েক ঘন্টা সময় নেবে।
সালভাদোর ডালি

বস্তুর তালিকার একটি বৈশিষ্ট্যের তুলনা সম্পর্কে কী? এই সমাধান ব্যবহার করে কি সম্ভব?
chovy

2
a.filter(x => !b1.has(x))সহজ। এবং নোটটি নোট করুন কেবলমাত্র জটিলতার জন্য গড়পড়তা সাবলাইনারের n * f(m) + mসাথে থাকা প্রয়োজন f(m)। এটি এর চেয়ে ভাল n * mতবে অগত্যা নয় n + m
ওরিওল

2
@ সালভাদোরডালি আপনি var difference = [...new Set([...a].filter(x => !b1.has(x)))];কেন নকল 'একটি' অ্যারে তৈরি করছেন? আপনি কেন ফিল্টারের ফলাফলকে একটি সেটে পরিণত করছেন এবং তারপরে আবার অ্যারে পরিণত করছেন? এটি কি সমান নয়var difference = a.filter(x => !b1.has(x));
দীপক মিত্তাল

13

ES2015 এর সাথে কার্যকরী পন্থা

গণনা difference মধ্যে দুইটি অ্যারের এক Setঅপারেশন। শব্দটি ইতিমধ্যে ইঙ্গিত দেয় যে দেশীয় Setপ্রকারটি ব্যবহার করা উচিত, যাতে দেখার গতি বাড়ে। যাইহোক, আপনি দুটি সেট এর মধ্যে পার্থক্য গণনা করার সময় তিনটি অনুমতি দেওয়া আছে:

[+left difference] [-intersection] [-right difference]
[-left difference] [-intersection] [+right difference]
[+left difference] [-intersection] [+right difference]

এখানে এই ক্রিয়াকলাপগুলি প্রতিফলিত করে একটি কার্যকরী সমাধান।

বাম difference:

// small, reusable auxiliary functions

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


// left difference

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


// mock data

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


// run the computation

console.log( differencel(xs) (ys) );

ডান difference:

differencerতুচ্ছ এটা শুধুdifferencel উল্টানো যুক্তি । আপনি সুবিধার জন্য একটি ফাংশন লিখতে পারেন:const differencer = flip(differencel)। এখানেই শেষ!

ভারসাম্য-সংক্রান্ত difference :

এখন যেহেতু আমাদের বাম এবং ডান এক আছে, প্রতিসাম্য প্রয়োগ করা differenceতুচ্ছ হয়ে যায়:

// small, reusable auxiliary functions

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


// left difference

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


// symmetric difference

const difference = ys => xs =>
 concat(differencel(xs) (ys)) (flip(differencel) (xs) (ys));

// mock data

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


// run the computation

console.log( difference(xs) (ys) );

আমি অনুমান করি যে কার্যকরী প্রোগ্রামিংয়ের অর্থ কী এমন একটি ধারণা অর্জনের জন্য এই উদাহরণটি একটি ভাল সূচনা পয়েন্ট:

বিল্ডিং ব্লকগুলির সাথে প্রোগ্রামিং যা বিভিন্ন উপায়ে একসাথে প্লাগ করা যায়।


12

একটি সমাধান ব্যবহার করে indexOf()ছোট অ্যারেগুলি ঠিক হবে তবে তারা দৈর্ঘ্যে বৃদ্ধির সাথে অ্যালগোরিদম পদ্ধতির কার্য সম্পাদন করবে O(n^2)। এখানে এমন একটি সমাধান রয়েছে যা কী হিসাবে অ্যারের এন্ট্রিগুলিকে সঞ্চয় করতে অ্যাসোসিয়েটিভ অ্যারে হিসাবে অবজেক্টগুলি ব্যবহার করে খুব বড় অ্যারেগুলির জন্য আরও ভাল সম্পাদন করবে; এটি স্বয়ংক্রিয়ভাবে সদৃশ এন্ট্রিগুলিও সরিয়ে দেয় তবে কেবল স্ট্রিং মানগুলি (বা মানগুলি যা নিরাপদে স্ট্রিং হিসাবে সংরক্ষণ করা যেতে পারে) নিয়ে কাজ করে:

function arrayDiff(a1, a2) {
  var o1={}, o2={}, diff=[], i, len, k;
  for (i=0, len=a1.length; i<len; i++) { o1[a1[i]] = true; }
  for (i=0, len=a2.length; i<len; i++) { o2[a2[i]] = true; }
  for (k in o1) { if (!(k in o2)) { diff.push(k); } }
  for (k in o2) { if (!(k in o1)) { diff.push(k); } }
  return diff;
}

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
arrayDiff(a1, a2); // => ['c', 'd']
arrayDiff(a2, a1); // => ['c', 'd']

আপনি যখনই কোনও জিনিসে "ইন" করছেন তখন অবজেক্ট.হসঅনপ্রপার্টি () ব্যবহার করতে চান। অন্যথায় আপনি প্রতিটি ক্ষেত্রের লুপিংয়ের ঝুঁকিটি ডিফল্ট অবজেক্টের প্রোটোটাইপে যুক্ত করেন। (অথবা কেবলমাত্র আপনার অবজেক্টের পিতামাতা) এছাড়াও আপনার কেবল দুটি লুপের দরকার, একটি হ্যাশ টেবিল তৈরির জন্য এবং অন্যটি সেই হ্যাশ টেবিলটিতে দেখায়।
jholloman

1
@ jholloman আমি শ্রদ্ধার সাথে একমত নই । এখন যেহেতু আমরা যে কোনও সম্পত্তির জন্য গণ্যকরণ নিয়ন্ত্রণ করতে পারি, সম্ভবত আপনি গণনার সময় যে কোনও সম্পত্তি পাবেন তার অন্তর্ভুক্ত থাকা উচিত
ফ্রেগজ

1
@ ফ্রোগজ একটি ভাল পয়েন্ট যদি আপনি কেবল আধুনিক ব্রাউজারগুলি সম্পর্কে উদ্বিগ্ন থাকেন। দুর্ভাগ্যক্রমে আমাকে আই 7 এ ফিরে সমর্থন করতে হবে তাই পাথর বয়সটি আমার চিন্তার ডিফল্ট ট্রেন এবং আমরা শিম ব্যবহার করার ঝোঁক রাখি না।
jholloman

10

জোশাভেন পটারের উপরের উত্তরটি দুর্দান্ত। তবে এটি অ্যারে বি তে এমন উপাদানগুলি ফেরত পাঠায় যা অ্যারে সি তে নয়, তবে অন্যভাবে নয়। উদাহরণস্বরূপ, যদি var a=[1,2,3,4,5,6].diff( [3,4,5,7]);তবে এটি আউটপুট হবে: ==> [1,2,6]তবে না [1,2,6,7] , যা উভয়ের মধ্যে প্রকৃত পার্থক্য। আপনি এখনও উপরে পটারের কোড ব্যবহার করতে পারেন তবে একবারের তুলনায় খুব সহজেই আবার করুন:

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return !(a.indexOf(i) > -1);});
};

////////////////////  
// Examples  
////////////////////

var a=[1,2,3,4,5,6].diff( [3,4,5,7]);
var b=[3,4,5,7].diff([1,2,3,4,5,6]);
var c=a.concat(b);
console.log(c);

এটি আউটপুট করা উচিত: [ 1, 2, 6, 7 ]


9

সমস্যা সমাধানের আর একটি উপায়

function diffArray(arr1, arr2) {
    return arr1.concat(arr2).filter(function (val) {
        if (!(arr1.includes(val) && arr2.includes(val)))
            return val;
    });
}

diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]);    // return [7, 4, 5]

এছাড়াও, আপনি তীর ফাংশন সিনট্যাক্স ব্যবহার করতে পারেন:

const diffArray = (arr1, arr2) => arr1.concat(arr2)
    .filter(val => !(arr1.includes(val) && arr2.includes(val)));

diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]);    // return [7, 4, 5]

7
Array.prototype.difference = function(e) {
    return this.filter(function(i) {return e.indexOf(i) < 0;});
};

eg:- 

[1,2,3,4,5,6,7].difference( [3,4,5] );  
 => [1, 2, 6 , 7]

আপনার কোনও নেটিভ অবজেক্ট এভাবে বাড়ানো উচিত নয়। যদি মানটি differenceকোনও ভবিষ্যতের সংস্করণে ফাংশন হিসাবে পরিচিত হয় এবং এই ফাংশনটির পরে আলাদা ফাংশনের স্বাক্ষর থাকে তবে আপনার, এটি আপনার কোড বা বিদেশী লাইব্রেরিগুলিকে ভেঙে দেবে যা এই ফাংশনটি ব্যবহার করে।
t.niese

7

জাভাস্ক্রিপ্টের ফিল্টার ফাংশন সহ খুব সহজ সমাধান:

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

function diffArray(arr1, arr2) {
  var newArr = [];
  var myArr = arr1.concat(arr2);
  
    newArr = myArr.filter(function(item){
      return arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0;
    });
   alert(newArr);
}

diffArray(a1, a2);


6

এটি সম্পর্কে:

Array.prototype.contains = function(needle){
  for (var i=0; i<this.length; i++)
    if (this[i] == needle) return true;

  return false;
} 

Array.prototype.diff = function(compare) {
    return this.filter(function(elem) {return !compare.contains(elem);})
}

var a = new Array(1,4,7, 9);
var b = new Array(4, 8, 7);
alert(a.diff(b));

সুতরাং এইভাবে আপনি array1.diff(array2)তাদের পার্থক্যটি পেতে পারেন (অ্যালগোরিদমের জন্য ভয়ঙ্কর সময় জটিলতা যদিও - ও (অ্যারে 1


ফিল্টার অপশনটি ব্যবহার করা একটি দুর্দান্ত ধারণা ... তবে, অ্যারের জন্য আপনার কোনও অন্তর্ভুক্ত পদ্ধতি তৈরি করার দরকার নেই। আমি আপনার ধারণাটিকে এক লাইনে পরিণত করেছি ... অনুপ্রেরণার জন্য ধন্যবাদ!
জোশাভেন পটার

আপনাকে () ফাংশনটি সংজ্ঞায়িত করতে হবে না। জেএস অন্তর্ভুক্ত () একই জিনিস।
দা ম্যান

4

আপনি করতে পারেন http://phrogz.net/JS/ArraySetMath.js ব্যবহার করে :

var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];

var array3 = array2.subtract( array1 );
// ["test5", "test6"]

var array4 = array1.exclusion( array2 );
// ["test5", "test6"]

4
function diffArray(arr1, arr2) {
  var newArr = arr1.concat(arr2);
  return newArr.filter(function(i){
    return newArr.indexOf(i) == newArr.lastIndexOf(i);
  });
}

এটা আমার জন্য কাজ করে


3
  • খাঁটি জাভাস্ক্রিপ্ট সমাধান (কোনও লাইব্রেরি নেই)
  • পুরানো ব্রাউজারগুলির সাথে সামঞ্জস্যপূর্ণ (ব্যবহার করে না filter)
  • হে (ঢ ^ 2)
  • Ption fnচ্ছিক কলব্যাক পরামিতি যা আপনাকে অ্যারে আইটেমগুলির তুলনা করতে নির্দিষ্ট করে দেয়

function diff(a, b, fn){
    var max = Math.max(a.length, b.length);
        d = [];
    fn = typeof fn === 'function' ? fn : false
    for(var i=0; i < max; i++){
        var ac = i < a.length ? a[i] : undefined
            bc = i < b.length ? b[i] : undefined;
        for(var k=0; k < max; k++){
            ac = ac === undefined || (k < b.length && (fn ? fn(ac, b[k]) : ac == b[k])) ? undefined : ac;
            bc = bc === undefined || (k < a.length && (fn ? fn(bc, a[k]) : bc == a[k])) ? undefined : bc;
            if(ac == undefined && bc == undefined) break;
        }
        ac !== undefined && d.push(ac);
        bc !== undefined && d.push(bc);
    }
    return d;
}

alert(
    "Test 1: " + 
    diff(
        [1, 2, 3, 4],
        [1, 4, 5, 6, 7]
      ).join(', ') +
    "\nTest 2: " +
    diff(
        [{id:'a',toString:function(){return this.id}},{id:'b',toString:function(){return this.id}},{id:'c',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
        [{id:'a',toString:function(){return this.id}},{id:'e',toString:function(){return this.id}},{id:'f',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
        function(a, b){ return a.id == b.id; }
    ).join(', ')
);


আপনি আরও কিছু গতি বার করতে দৈর্ঘ্যের মানগুলি ক্যাশে করতে পারেন। আমি দৈর্ঘ্য পরীক্ষা না করে অ্যারে উপাদানগুলিতে অ্যাক্সেসের সুপারিশ করতে চেয়েছিলাম, তবে স্পষ্টতই সরল চেকটি প্রায় 100x স্পিডআপ দেয়।
স্লোটো

lengthমানগুলি ক্যাশে করার কোনও কারণ নেই । এটি ইতিমধ্যে সরল সম্পত্তি। jsperf.com/array-leight-caching
vp_arth

3

এটি কাজ করছে: মূলত দুটি অ্যারে একীভূত করুন, সদৃশ সন্ধান করুন এবং ডুপ্লিকেট নয় এমন একটি নতুন অ্যারেতে চাপ দিন যা পার্থক্য।

function diff(arr1, arr2) {
  var newArr = [];
  var arr = arr1.concat(arr2);
  
  for (var i in arr){
    var f = arr[i];
    var t = 0;
    for (j=0; j<arr.length; j++){
      if(arr[j] === f){
        t++; 
        }
    }
    if (t === 1){
      newArr.push(f);
        }
  } 
  return newArr;
}


3

// এস 6 পদ্ধতি

function diff(a, b) {
  var u = a.slice(); //dup the array
  b.map(e => {
    if (u.indexOf(e) > -1) delete u[u.indexOf(e)]
    else u.push(e)   //add non existing item to temp array
  })
  return u.filter((x) => {return (x != null)}) //flatten result
}

3

প্রতিসম এবং লিনিয়ার জটিলতা । ES6 প্রয়োজন।

function arrDiff(arr1, arr2) {
    var arrays = [arr1, arr2].sort((a, b) => a.length - b.length);
    var smallSet = new Set(arrays[0]);

    return arrays[1].filter(x => !smallSet.has(x));
}

3

এখনও অন্য উত্তর, তবে মনে হয় কেউ জাস্পফারফের উল্লেখ করেনি যেখানে তারা বেশ কয়েকটি অ্যালগোরিদম এবং প্রযুক্তি সমর্থন সমর্থন করে: https://jsperf.com/array-differences- জাভাস্ক্রিপ্ট ফিল্টার ব্যবহার করার ফলে সেরা ফলাফল পাওয়া যায় বলে মনে হয়। ধন্যবাদ


2

কেবল একটি চ্যালেঞ্জের জন্যই চিন্তা করা ;-) এই কাজ করবে ... (স্ট্রিং, সংখ্যা ইত্যাদির প্রাথমিক অ্যারেগুলির জন্য) কোনও নেস্টেড অ্যারে

function diffArrays(arr1, arr2, returnUnion){
  var ret = [];
  var test = {};
  var bigArray, smallArray, key;
  if(arr1.length >= arr2.length){
    bigArray = arr1;
    smallArray = arr2;
  } else {
    bigArray = arr2;
    smallArray = arr1;
  }
  for(var i=0;i<bigArray.length;i++){
    key = bigArray[i];
    test[key] = true;
  }
  if(!returnUnion){
    //diffing
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = null;
      }
    }
  } else {
    //union
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = true;
      }
    }
  }
  for(var i in test){
    ret.push(i);
  }
  return ret;
}

array1 = "test1", "test2","test3", "test4", "test7"
array2 = "test1", "test2","test3","test4", "test5", "test6"
diffArray = diffArrays(array1, array2);
//returns ["test5","test6","test7"]

diffArray = diffArrays(array1, array2, true);
//returns ["test1", "test2","test3","test4", "test5", "test6","test7"]

নোট করুন বাছাই করা সম্ভবত উপরে উল্লিখিত হিসাবে থাকবে না ... তবে যদি ইচ্ছা হয় তবে সাজানোর জন্য অ্যারেতে .sort () কল করুন।


2

আমি একটি অনুরূপ ফাংশন চেয়েছিলাম যা একটি পুরাতন অ্যারে এবং একটি নতুন অ্যারে নিয়েছিল এবং আমাকে যুক্ত করা আইটেমগুলির একটি অ্যারে এবং সরানো আইটেমগুলির একটি অ্যারে দিয়েছিল, এবং আমি এটি দক্ষ হতে চেয়েছি (সুতরাং কোনও নিয়ন্ত্রণ নেই!)।

আপনি আমার প্রস্তাবিত সমাধানটি এখানে খেলতে পারেন: http://jsbin.com/osewu3/12

কেউ কি সেই অ্যালগরিদমে কোনও সমস্যা / উন্নতি দেখতে পাবে? ধন্যবাদ!

কোড তালিকা:

function diff(o, n) {
  // deal with empty lists
  if (o == undefined) o = [];
  if (n == undefined) n = [];

  // sort both arrays (or this won't work)
  o.sort(); n.sort();

  // don't compare if either list is empty
  if (o.length == 0 || n.length == 0) return {added: n, removed: o};

  // declare temporary variables
  var op = 0; var np = 0;
  var a = []; var r = [];

  // compare arrays and add to add or remove lists
  while (op < o.length && np < n.length) {
      if (o[op] < n[np]) {
          // push to diff?
          r.push(o[op]);
          op++;
      }
      else if (o[op] > n[np]) {
          // push to diff?
          a.push(n[np]);
          np++;
      }
      else {
          op++;np++;
      }
  }

  // add remaining items
  if( np < n.length )
    a = a.concat(n.slice(np, n.length));
  if( op < o.length )
    r = r.concat(o.slice(op, o.length));

  return {added: a, removed: r}; 
}

2

আমি একটি সাধারণ উত্তর খুঁজছিলাম যা বিভিন্ন লাইব্রেরি ব্যবহার করে না জড়িত, এবং আমি আমার নিজের সাথে এসেছি যা আমি মনে করি না যে এখানে উল্লেখ করা হয়েছে। আমি জানি না এটি কতটা দক্ষ বা কিছুই কাজ করে;

    function find_diff(arr1, arr2) {
      diff = [];
      joined = arr1.concat(arr2);
      for( i = 0; i <= joined.length; i++ ) {
        current = joined[i];
        if( joined.indexOf(current) == joined.lastIndexOf(current) ) {
          diff.push(current);
        }
      }
      return diff;
    }

আমার কোডের জন্য আমার ডুপ্লিকেটগুলিও বাইরে নেওয়া দরকার তবে আমি অনুমান করি যে এটি সর্বদা পছন্দ নয়।

আমি অনুমান করি যে মূল ক্ষতিটি হ'ল এটি সম্ভাব্যভাবে অনেক বিকল্পের সাথে তুলনা করছে যা ইতিমধ্যে প্রত্যাখ্যাত হয়েছে।


2

সেরা উত্তরের জন্য লিটলবিট ঠিক করুন

function arr_diff(a1, a2)
{
  var a=[], diff=[];
  for(var i=0;i<a1.length;i++)
    a[a1[i]]=a1[i];
  for(var i=0;i<a2.length;i++)
    if(a[a2[i]]) delete a[a2[i]];
    else a[a2[i]]=a2[i];
  for(var k in a)
   diff.push(a[k]);
  return diff;
}

এটি বিবেচনা করে বর্তমান ধরণের উপাদান গ্রহণ করবে। খ / সি আমরা যখন [a1 [i]] তৈরি করি তখন এটি একটি মানকে এর অরগিনাল মান থেকে স্ট্রিংয়ে রূপান্তর করে, তাই আমরা প্রকৃত মানটি হারাতে পারি।


এটি এখনও অবজেক্টগুলির অ্যারের জন্য ব্যর্থ। var a = [{a: 1}], বি = [{বি: 2}] আরআর_ডিফ (ক, খ) == []।
এরিকপি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.