क्या जावास्क्रिप्ट में दो सरणियों के बीच अंतर को वापस करने का एक तरीका है?
उदाहरण के लिए:
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
O(a1.length x log(a2.length))
- यह प्रदर्शन जावास्क्रिप्ट में संभव है?
क्या जावास्क्रिप्ट में दो सरणियों के बीच अंतर को वापस करने का एक तरीका है?
उदाहरण के लिए:
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
O(a1.length x log(a2.length))
- यह प्रदर्शन जावास्क्रिप्ट में संभव है?
जवाबों:
मुझे लगता है कि आप एक सामान्य सरणी की तुलना कर रहे हैं। यदि नहीं, तो आप को बदलने की जरूरत के लिए पाश एक करने के लिए में .. के लिए पाश।
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"));
एक बेहतर समाधान, यदि आप पिछड़े संगतता के बारे में परवाह नहीं करते हैं, तो फिल्टर का उपयोग कर रहा है। लेकिन फिर भी, यह समाधान काम करता है।
var a1 = ['a', 'b'];
और क्या हो जाए var a2 = ['a', 'b', 'c', 'd', 'b'];
, यह गलत उत्तर लौटाएगा , अर्थात ['c', 'd', 'b']
इसके बजाय ['c', 'd']
।
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; }
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)));
इस तरह, आपको एरी 1 के सभी तत्वों से युक्त एक सरणी मिलेगी जो एरे 2 और इसके विपरीत नहीं है
जैसा कि @ जोशेन पॉटर ने अपने जवाब में बताया, आप इसे Array.prototype में जोड़ सकते हैं ताकि इसे इस तरह बनाया जा सके:
Array.prototype.diff = function(arr2) { return this.filter(x => !arr2.includes(x)); }
[1, 2, 3].diff([2, 3])
< 0
इसके बजाय की जाँच करना पसंद करता हूँ== -1
Array
अंतर को समझना एक तथाकथित है set operation
, क्योंकि संपत्ति की खोज एस का बहुत ही काम है Set
, जो कि तब तीव्रता के आदेश हैं indexOf
/ includes
। सीधे शब्दों में कहें, तो आपका समाधान बहुत ही अक्षम और धीमा है।
Set
, मूल्यों के लिए अद्वितीय होना चाहिए, नहीं?
[1,2,3] [2,3,5]
कि नंबर अद्वितीय हैं लेकिन अगर आपने कहा था [1,1,2,3] [1,2,3,5]
और उम्मीद है कि [1]
आप उपयोग नहीं कर सकते Set
। हालांकि आपका समाधान या तो काम नहीं करेगा: - / मैंने इस फ़ंक्शन को बनाना समाप्त कर दिया है क्योंकि मैं इसे अधिक सफलतापूर्वक करने के लिए एक संतोषजनक तरीके का पता नहीं लगा सका। यदि आपके पास ऐसा करने के बारे में कोई विचार है, तो मुझे जानना अच्छा लगेगा!
Array.includes()
ES6 की जगह ES7 फीचर नहीं है ? (1) (2) - और जारी रखने के लिए, ES6 के साथ आप Array.some()
उदाहरण के लिए इस्तेमाल कर सकते हैं let intersection = aArray.filter(a => bArray.some(b => a === b))
, नहीं?
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"]
नोट इंडेक्सऑफ और फिल्टर आईई 9 से पहले उपलब्ध नहीं हैं।
[1,2,3].diff([3,4,5])
वापस आ [1,2]
जाएगा, [1,2,4,5]
इसलिए यह मूल प्रश्न में समस्या को हल नहीं करता है, कुछ के बारे में पता होना चाहिए।
यह अब तक का सबसे आसान तरीका है जिससे आप जिस परिणाम की तलाश कर रहे हैं, वह jQuery का उपयोग कर रहा है:
var diff = $(old_array).not(new_array).get();
diff
अब इसमें वह है जो इसमें old_array
नहीं थाnew_array
.not
किसी सरणी के साथ उपयोग करते हैं, तो jQuery इसका उपयोग करता है .grep()
जो अंतर्निहित उपयोगिता है जो विशेष रूप से फ़िल्टरिंग सरणियों के लिए है। मैं इसे बदलते नहीं देख सकता।
अंडरस्कोर में अंतर विधि (या इसके ड्रॉप-इन प्रतिस्थापन, लो-डैश ) भी ऐसा कर सकते हैं:
(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]);
"अंतर" के लिए दो संभावित अंतर्ग्रहण हैं। मैं आपको वह चुनने दूंगा जो आप चाहते हैं। आप कहें:
var a1 = ['a', 'b' ];
var a2 = [ 'b', 'c'];
यदि आप प्राप्त करना चाहते हैं ['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;
}
यदि आप प्राप्त करना चाहते हैं ['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) का उपयोग कर सकते हैं ।
यदि आप Underscore.js का उपयोग कर रहे हैं, तो आप उपयोग कर सकते हैं _.difference(a1, a2)
केस 1 के लिए फ़ंक्शन का ।
उपरोक्त कोड सभी ब्राउज़रों पर काम करता है। हालांकि, लगभग 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 या विरल सरणियों की परवाह करते हैं तो सभी उदाहरणों के लिए व्यवहार आश्चर्यजनक या गैर-स्पष्ट हो सकता है । (अधिकांश उपयोगों के लिए, यह कोई मायने नहीं रखता है।)
सममित अंतर प्राप्त करने के लिए आपको दोनों तरीकों से सरणियों की तुलना करने की आवश्यकता है (या कई सरणियों के मामले में सभी तरीकों से)
// 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));
}));
}
// 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);
}));
}
// 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}]
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']
: ई निकाला नहीं जाएगा।
आप इस मामले में एक सेट का उपयोग कर सकते हैं । यह इस तरह के ऑपरेशन (संघ, चौराहे, अंतर) के लिए अनुकूलित है।
सुनिश्चित करें कि यह आपके मामले पर लागू होता है, एक बार यह कोई डुप्लिकेट की अनुमति नहीं देता है।
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}
Set
सब कुछ पाने के लिए सिर्फ फ़ंक्शन डाउनलोड नहीं कर सकते ...
function diff(a1, a2) {
return a1.concat(a2).filter(function(val, index, arr){
return arr.indexOf(val) === arr.lastIndexOf(val);
});
}
दोनों सरणियों को मर्ज करें, अद्वितीय मान केवल एक बार दिखाई देंगे ताकि इंडेक्सऑफ () लास्टइंडेक्सऑफ () के समान हो।
एक सरणी को दूसरे से घटाने के लिए, बस नीचे दिए गए स्निपेट का उपयोग करें:
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;
});
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)))
O(n + m)
आपका समाधान वह O(n * m)
जगह है जहाँ n और m लम्बाई के सरणियाँ हैं। लंबी सूची लें और मेरा समाधान सेकंड में चलेगा, जबकि आपका समय लगेगा।
a.filter(x => !b1.has(x))
सरल है। और ध्यान दें कि कल्पना को केवल औसत के n * f(m) + m
साथ जटिलता की आवश्यकता होती है f(m)
। यह बेहतर है n * m
, लेकिन जरूरी नहीं है n + m
।
var difference = [...new Set([...a].filter(x => !b1.has(x)))];
आप डुप्लिकेट 'ए' सरणी क्यों बना रहे हैं? आप एक सेट में फ़िल्टर का परिणाम क्यों बदल रहे हैं और फिर वापस सरणी में हैं? इस के बराबर नहीं हैvar difference = a.filter(x => !b1.has(x));
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) );
मुझे लगता है कि इस उदाहरण को एक छाप प्राप्त करने के लिए एक अच्छा प्रारंभिक बिंदु है जो कार्यात्मक प्रोग्रामिंग का मतलब है:
बिल्डिंग ब्लॉक्स के साथ प्रोग्रामिंग जो कई अलग-अलग तरीकों से एक साथ प्लग की जा सकती है।
एक समाधान का उपयोग 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']
जोशवेन पॉटर द्वारा उपरोक्त उत्तर महान है। लेकिन यह सरणी B में ऐसे तत्व देता है जो सरणी C में नहीं हैं, लेकिन दूसरे तरीके से नहीं। उदाहरण के लिए, यदि 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 ]
समस्या को हल करने का दूसरा तरीका
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]
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
भविष्य के संस्करण में फ़ंक्शन के रूप में परिचय देता है और इस फ़ंक्शन का फिर एक अलग फ़ंक्शन हस्ताक्षर होता है तो आपका, यह आपके कोड या विदेशी पुस्तकालयों को तोड़ देगा जो इस फ़ंक्शन का उपयोग करते हैं।
जावास्क्रिप्ट के फिल्टर फ़ंक्शन के साथ बहुत सरल समाधान:
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);
इस बारे में कैसा है:
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)
उनके अंतर को प्राप्त कर सकते हैं (एल्गोरिथम के लिए भयानक समय जटिलता हालांकि - ओ (array1.length x array2.length) मेरा मानना है)
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"]
filter
)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(', ')
);
length
मूल्यों को कैश करने का कोई कारण नहीं । यह पहले से ही सादे संपत्ति है। jsperf.com/array-length-caching
यह काम कर रहा है: मूल रूप से दो सरणियों को मर्ज करें, डुप्लिकेट की तलाश करें और जो एक नए सरणी में अंतर नहीं है, उसे दोहराएं।
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;
}
// es6 दृष्टिकोण
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
}
अभी तक एक और जवाब है, लेकिन ऐसा लगता है कि किसी ने भी jsperf का उल्लेख नहीं किया है, जहां वे कई एल्गोरिदम और प्रौद्योगिकी समर्थन की तुलना करते हैं: https://jsperf.com/array-difference-javascript का उपयोग करके लगता है कि फ़िल्टर का सबसे अच्छा परिणाम मिलता है। धन्यवाद
सिर्फ सोच ... एक चुनौती के लिए ;-) क्या यह काम करेगा ... (स्ट्रिंग्स, संख्याओं, आदि के मूल सरणियों के लिए) कोई शून्य सरणियाँ नहीं
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 () कॉल करें।
मैं एक समान फ़ंक्शन चाहता था जो एक पुराने सरणी और एक नए सरणी में ले गया और मुझे अतिरिक्त वस्तुओं का एक सरणी और हटाए गए आइटमों का एक सरणी दिया, और मैं चाहता था कि यह कुशल हो (इसलिए नहीं। कोई नहीं!)।
: तुम मेरी प्रस्तावित समाधान यहाँ के साथ खेल सकते 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};
}
मैं एक सरल उत्तर की तलाश में था जिसमें विभिन्न पुस्तकालयों का उपयोग शामिल नहीं था, और मैं अपने साथ आया था कि मुझे नहीं लगता कि यहां उल्लेख किया गया है। मुझे नहीं पता कि यह कितना कुशल है या कुछ भी लेकिन यह काम करता है;
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;
}
मेरे कोड के लिए मुझे डुप्लिकेट के रूप में अच्छी तरह से बाहर निकालने की आवश्यकता है, लेकिन मुझे लगता है कि हमेशा पसंद नहीं किया जाता है।
मुझे लगता है कि मुख्य नकारात्मक पक्ष यह संभावित रूप से कई विकल्पों की तुलना कर रहा है जो पहले ही खारिज कर दिए गए हैं।
सबसे अच्छा जवाब के लिए थोड़ा तय
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] बनाते हैं, तो यह एक मान को उसके ऑरलिनल वैल्यू से स्ट्रिंग में परिवर्तित कर देता है, इसलिए हमने एक और वैल्यू खो दी है।