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




arrays array-difference (20)

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

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

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

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

কোন পরামর্শ ব্যাপকভাবে প্রশংসা।


ES2015 সঙ্গে কার্যকরী পদ্ধতির

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

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

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

বাম 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 তুচ্ছ হয়। এটা flipped আর্গুমেন্ট সঙ্গে শুধু 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) );

আমি অনুমান করছি যে এই উদাহরণটি একটি কার্যকর সূচনা যা কার্যকরী প্রোগ্রামিং মানে একটি ছাপ পেতে:

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


সাধারণ জাভাস্ক্রিপ্ট

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

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 এর জন্য _.difference(a1, a2) ফাংশন ব্যবহার করতে পারেন।

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

উপরে কোড সব ব্রাউজারে কাজ করে। তবে, প্রায় 10,000 টিরও বেশি আইটেমের বড় অ্যারেগুলির জন্য, এটি বেশ ধীর হয়ে যায়, কারণ এটিতে O (n²) জটিলতা রয়েছে। অনেক আধুনিক ব্রাউজারে, আমরা গতি বাড়ানোর জন্য ES6 Set বস্তুর সুবিধা নিতে পারি। লোডশ যখন এটি উপলব্ধ তখন স্বয়ংক্রিয়ভাবে 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, নাএন বা স্পারস অ্যারের যত্ন করেন তবে সমস্ত উদাহরণের জন্য আচরণ বিস্ময়কর বা অ-সুস্পষ্ট হতে পারে। (সর্বাধিক ব্যবহারের জন্য, এটি কোন ব্যাপার নয়।)


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

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

diff এখন আছে old_array যা ছিল old_array নয়


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

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;
});

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

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"));

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


এই চিন্তার দ্বারা গৃহীত উত্তর দ্বারা অনুপ্রাণিত ছিল, কিন্তু চিন্তাবিদ এর উত্তর অ্যারে সেট হয় অনুমান করা হয়। যদি অ্যারেগুলি [ "1", "2" ] এবং [ "1", "1", "2", "2" ]

ঐ অ্যারের মধ্যে পার্থক্য [ "1", "2" ] । নিম্নলিখিত সমাধানটি হল O (n * n), তাই আদর্শ নয়, তবে আপনার যদি বড় অ্যারে থাকে, তবে এর সাথে চিন্তার সমাধানটির মেমরি সুবিধাও রয়েছে।

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

if (!Array.prototype.diff) { 
    Array.prototype.diff = function (array) {
        // if the other array is a falsy value, return a copy of this array
        if ((!array) || (!Array.prototype.isPrototypeOf(array))) { 
            return this.slice(0);
        }

        var diff = [];
        var original = this.slice(0);

        for(var i=0; i < array.length; ++i) {
            var index = original.indexOf(array[i]);
            if (index > -1) { 
                original.splice(index, 1);
            } else { 
                diff.push(array[i]);
            }
        }

        for (var i=0; i < original.length; ++i) {
            diff.push(original[i]);
        }
        return diff;
    }
}   

কিভাবে এই সম্পর্কে:

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. লম্বা x অ্যারে 2. দৈর্ঘ্য) আমি বিশ্বাস করি)


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

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);


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

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 () কল করুন।


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

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]

সেরা উত্তর জন্য সামান্য বিট

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;
}

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


// এস 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
}

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

(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]);

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']

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

আপনি এখানে আমার প্রস্তাবিত সমাধান দিয়ে খেলতে পারেন: 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}; 
}

যদি অ্যারেগুলি সাধারণ ধরনের না হয়, তাহলে উপরে দেওয়া উত্তরগুলির মধ্যে একটিটি অভিযোজিত করা যেতে পারে:

Array.prototype.diff = function(a) {
        return this.filter(function(i) {return a.map(function(e) { return JSON.stringify(e); }).indexOf(JSON.stringify(i)) < 0;});
    };

এই পদ্ধতি জটিল বস্তুর অ্যারে কাজ করে।


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

অ্যারে উভয় মার্জ করুন, অনন্য মান শুধুমাত্র একবার প্রদর্শিত হবে সুতরাং indexOf () শেষ EndEndex () হিসাবে একই হবে।


function diff(arr1, arr2) {
  var filteredArr1 = arr1.filter(function(ele) {
    return arr2.indexOf(ele) == -1;
  });

  var filteredArr2 = arr2.filter(function(ele) {
    return arr1.indexOf(ele) == -1;
  });
  return filteredArr1.concat(filteredArr2);
}

diff([1, "calf", 3, "piglet"], [1, "calf", 3, 4]); // Log ["piglet",4]

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

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

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

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


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

উল্লেখ্য indexOf এবং ফিল্টার ie9 আগে অর্থাত্ পাওয়া যায় না।


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]





array-difference