जावास्क्रिप्ट में सरणी चौराहों को लागू करने के लिए सबसे सरल, पुस्तकालय-मुक्त कोड क्या है? मैं लिखना चाहता हूँ
intersection([1,2,3], [2,3,4,5])
और पाओ
[2, 3]
break
को Simple js loops
बढ़ाने के लिए a को जोड़ना ~ 10M
जावास्क्रिप्ट में सरणी चौराहों को लागू करने के लिए सबसे सरल, पुस्तकालय-मुक्त कोड क्या है? मैं लिखना चाहता हूँ
intersection([1,2,3], [2,3,4,5])
और पाओ
[2, 3]
break
को Simple js loops
बढ़ाने के लिए a को जोड़ना ~ 10M
जवाबों:
के संयोजन का प्रयोग Array.prototype.filter
और Array.prototype.indexOf
:
array1.filter(value => -1 !== array2.indexOf(value))
या जैसा कि टिप्पणियों में सुझाए गए vrugtehagel , आप और Array.prototype.includes
भी सरल कोड के लिए हाल ही में उपयोग कर सकते हैं :
array1.filter(value => array2.includes(value))
पुराने ब्राउज़रों के लिए:
array1.filter(function(n) {
return array2.indexOf(n) !== -1;
});
intersection([1,2,1,1,3], [1])
लौटता है [1, 1, 1]
। क्या यह अभी वापस नहीं आना चाहिए [1]
?
array2.indexOf(n) != -1
एक array2.includes(n)
भी सरल कोड के लिए लिख सकते हैं ।
विनाशकारी सबसे सरल लगता है, खासकर अगर हम मान सकते हैं कि इनपुट सॉर्ट किया गया है:
/* destructively finds the intersection of
* two arrays in a simple fashion.
*
* PARAMS
* a - first array, must already be sorted
* b - second array, must already be sorted
*
* NOTES
* State of input arrays is undefined when
* the function returns. They should be
* (prolly) be dumped.
*
* Should have O(n) operations, where n is
* n = MIN(a.length, b.length)
*/
function intersection_destructive(a, b)
{
var result = [];
while( a.length > 0 && b.length > 0 )
{
if (a[0] < b[0] ){ a.shift(); }
else if (a[0] > b[0] ){ b.shift(); }
else /* they're equal */
{
result.push(a.shift());
b.shift();
}
}
return result;
}
गैर-विनाशकारी बालों को अधिक जटिल होना पड़ता है, क्योंकि हमें सूचकांक ट्रैक करने के लिए मिला है:
/* finds the intersection of
* two arrays in a simple fashion.
*
* PARAMS
* a - first array, must already be sorted
* b - second array, must already be sorted
*
* NOTES
*
* Should have O(n) operations, where n is
* n = MIN(a.length(), b.length())
*/
function intersect_safe(a, b)
{
var ai=0, bi=0;
var result = [];
while( ai < a.length && bi < b.length )
{
if (a[ai] < b[bi] ){ ai++; }
else if (a[ai] > b[bi] ){ bi++; }
else /* they're equal */
{
result.push(a[ai]);
ai++;
bi++;
}
}
return result;
}
intersect_safe
: length
एरेस में एक संपत्ति है, एक विधि नहीं है। इसमें एक अनियंत्रित चर i
है result.push(a[i]);
। अंत में, यह केवल सामान्य स्थिति में काम नहीं करता है: दो वस्तुएं जहां >
ऑपरेटर के अनुसार न तो दूसरे की तुलना में अधिक हो, जरूरी नहीं कि समान हो। intersect_safe( [ {} ], [ {} ] )
, उदाहरण के लिए, एक तत्व के साथ एक सरणी (एक बार पहले उल्लिखित त्रुटियों को ठीक कर दिया जाता है) देगा, जो स्पष्ट रूप से गलत है।
.slice(0)
सरणी का एक क्लोन बनाने के लिए भी उपयोग कर सकते हैं intersect_safe
।
यदि आपका वातावरण ECMAScript 6 सेट का समर्थन करता है , तो एक सरल और माना जाता है कि कुशल (विनिर्देश लिंक देखें):
function intersect(a, b) {
var setA = new Set(a);
var setB = new Set(b);
var intersection = new Set([...setA].filter(x => setB.has(x)));
return Array.from(intersection);
}
कम, लेकिन कम पठनीय (अतिरिक्त चौराहे बनाए बिना Set
):
function intersect(a, b) {
return [...new Set(a)].filter(x => new Set(b).has(x));
}
हर बार नए Set
से बचना b
:
function intersect(a, b) {
var setB = new Set(b);
return [...new Set(a)].filter(x => setB.has(x));
}
ध्यान दें कि सेट का उपयोग करते समय आपको केवल अलग-अलग मान प्राप्त होंगे, इस प्रकार इसका new Set[1,2,3,3].size
मूल्यांकन होता है 3
।
[...setA]
वाक्य रचना क्या है ? कुछ खास तरह के जावास्क्रिप्ट ऑपरेशन?
x => new Set(b).has(x)
तीर फ़ंक्शन b
एक सेट में नहीं बदल जाता है ? आपको शायद उस सेट को एक चर में सहेजना चाहिए।
Underscore.js या lodash.js का उपयोग करना
_.intersection( [0,345,324] , [1,0,324] ) // gives [0,324]
ईएस 6 शब्दों में मेरा योगदान। सामान्य तौर पर यह एक सरणी के चौराहे को तर्कों के रूप में प्रदान की गई अनिश्चित संख्या में अनिश्चित काल का होता है।
Array.prototype.intersect = function(...a) {
return [this,...a].reduce((p,c) => p.filter(e => c.includes(e)));
}
var arrs = [[0,2,4,6,8],[4,5,6,7],[4,6]],
arr = [0,1,2,3,4,5,6,7,8,9];
document.write("<pre>" + JSON.stringify(arr.intersect(...arrs)) + "</pre>");
[[0,1,2,3,4,5,6,7,8,9],[0,2,4,6,8],[4,5,6,7],[4,6]]
और फिर लागू होता है .reduce()
। सबसे पहले [0,1,2,3,4,5,6,7,8,9].filter( e => [0,2,4,6,8].includes(e)
आपरेशन किया जाता है और परिणाम नया हो जाता है p
और c
हो जाता है [4,5,6,7]
अगली बारी में और ऊपर पर तो जारी है जब तक कोई और अधिक c
छोड़ दिया है।
prototype
अनावश्यक रूप से संशोधित न करें ।
// Return elements of array a that are also in b in linear time:
function intersect(a, b) {
return a.filter(Set.prototype.has, new Set(b));
}
// Example:
console.log(intersect([1,2,3], [2,3,4,5]));
मैं उपर्युक्त समाधान की सलाह देता हूं जो बड़े इनपुट पर अन्य कार्यान्वयन को बेहतर बनाता है। यदि छोटे इनपुट मामलों पर प्रदर्शन, नीचे दिए गए विकल्पों की जाँच करें।
विकल्प और प्रदर्शन तुलना:
वैकल्पिक कार्यान्वयन के लिए निम्नलिखित स्निपेट देखें और प्रदर्शन तुलना के लिए https://jsperf.com/array-intersection-comparison देखें ।
फ़ायरफ़ॉक्स 53 में परिणाम:
बड़े सरणियों पर ऑप्स / सेक (10,000 तत्व):
filter + has (this) 523 (this answer)
for + has 482
for-loop + in 279
filter + in 242
for-loops 24
filter + includes 14
filter + indexOf 10
छोटे सरणियों पर ऑप्स / सेक (100 तत्व):
for-loop + in 384,426
filter + in 192,066
for-loops 159,137
filter + includes 104,068
filter + indexOf 71,598
filter + has (this) 43,531 (this answer)
filter + has (arrow function) 35,588
intersect([1,2,2,3], [2,3,4,5])
लौटता है [2, 2, 3]
।
a.filter(b.includes)
। यह काफी तेज चलना चाहिए (आपके फ़ंक्शन अपग्रेड के समान)।
कैसे सिर्फ साहचर्य सरणियों का उपयोग करने के बारे में?
function intersect(a, b) {
var d1 = {};
var d2 = {};
var results = [];
for (var i = 0; i < a.length; i++) {
d1[a[i]] = true;
}
for (var j = 0; j < b.length; j++) {
d2[b[j]] = true;
}
for (var k in d1) {
if (d2[k])
results.push(k);
}
return results;
}
संपादित करें:
// new version
function intersect(a, b) {
var d = {};
var results = [];
for (var i = 0; i < b.length; i++) {
d[b[i]] = true;
}
for (var j = 0; j < a.length; j++) {
if (d[a[j]])
results.push(a[j]);
}
return results;
}
Object.prototype
।
d[b[i]] = true;
इसके बजाय d[b[j]] = true;
( i
नहीं j
) होना चाहिए । लेकिन संपादित करने के लिए 6 वर्णों की आवश्यकता होती है।
कुछ इस तरह, हालांकि अच्छी तरह से परीक्षण नहीं किया गया।
function intersection(x,y){
x.sort();y.sort();
var i=j=0;ret=[];
while(i<x.length && j<y.length){
if(x[i]<y[j])i++;
else if(y[j]<x[i])j++;
else {
ret.push(x[i]);
i++,j++;
}
}
return ret;
}
alert(intersection([1,2,3], [2,3,4,5]));
पुनश्च: एल्गोरिथ्म केवल संख्या और सामान्य स्ट्रिंग्स के लिए अभिप्रेत है, मध्यस्थ ऑब्जेक्ट सरणियों का प्रतिच्छेदन काम नहीं कर सकता है।
आदिमों की सॉर्ट किए गए सरणियों के लिए @ एटीके के कार्यान्वयन का प्रदर्शन .shift के बजाय .op का उपयोग करके सुधार किया जा सकता है।
function intersect(array1, array2) {
var result = [];
// Don't destroy the original arrays
var a = array1.slice(0);
var b = array2.slice(0);
var aLast = a.length - 1;
var bLast = b.length - 1;
while (aLast >= 0 && bLast >= 0) {
if (a[aLast] > b[bLast] ) {
a.pop();
aLast--;
} else if (a[aLast] < b[bLast] ){
b.pop();
bLast--;
} else /* they're equal */ {
result.push(a.pop());
b.pop();
aLast--;
bLast--;
}
}
return result;
}
मैंने jsPerf: http://bit.ly/P9FrZK का उपयोग करके एक बेंचमार्क बनाया । यह उपयोग करने के लिए लगभग तीन गुना तेज है।
a[aLast] > b[bLast]
साथ a[aLast].localeCompare(b[bLast]) > 0
(और साथ ही else if
नीचे) तो यह तार पर काम करेंगे।
.pop
O (1) है और .shift()
O (n) है
JQuery का उपयोग करना :
var a = [1,2,3];
var b = [2,3,4,5];
var c = $(b).not($(b).not(a));
alert(c);
c = $(b).filter(a);
, लेकिन मैं इस तरह के सरणी हेरफेर के लिए jQuery पर भरोसा करने की सिफारिश नहीं करूंगा क्योंकि प्रलेखन में केवल यह उल्लेख है कि यह तत्वों के लिए काम करता है।
केवल स्ट्रिंग या संख्या वाले सरणियों के लिए आप कुछ अन्य उत्तरों के अनुसार छंटाई के साथ कुछ कर सकते हैं। मनमानी वस्तुओं के सरणियों के सामान्य मामले के लिए मुझे नहीं लगता कि आप इसे लंबा करने से बच सकते हैं। निम्नलिखित आपको मापदंडों के रूप में प्रदान की गई किसी भी संख्या में सरणियों का प्रतिच्छेदन देगा arrayIntersection
:
var arrayContains = Array.prototype.indexOf ?
function(arr, val) {
return arr.indexOf(val) > -1;
} :
function(arr, val) {
var i = arr.length;
while (i--) {
if (arr[i] === val) {
return true;
}
}
return false;
};
function arrayIntersection() {
var val, arrayCount, firstArray, i, j, intersection = [], missing;
var arrays = Array.prototype.slice.call(arguments); // Convert arguments into a real array
// Search for common values
firstArray = arrays.pop();
if (firstArray) {
j = firstArray.length;
arrayCount = arrays.length;
while (j--) {
val = firstArray[j];
missing = false;
// Check val is present in each remaining array
i = arrayCount;
while (!missing && i--) {
if ( !arrayContains(arrays[i], val) ) {
missing = true;
}
}
if (!missing) {
intersection.push(val);
}
}
}
return intersection;
}
arrayIntersection( [1, 2, 3, "a"], [1, "a", 2], ["a", 1] ); // Gives [1, "a"];
firstArr
या firstArray
संदर्भ के सभी अद्यतन नहीं किया था या नहीं, इस बारे में स्पष्ट रूप से मेरा विचार बदल गया । फिक्स्ड।
ES2015 और सेट का उपयोग करना बहुत छोटा है। स्ट्रिंग की तरह एरे-जैसे मानों को स्वीकार करता है और डुप्लिकेट को निकालता है।
let intersection = function(a, b) {
a = new Set(a), b = new Set(b);
return [...a].filter(v => b.has(v));
};
console.log(intersection([1,2,1,2,3], [2,3,5,4,5,3]));
console.log(intersection('ccaabbab', 'addb').join(''));
तुम एक इस्तेमाल कर सकते हैं Set
के रूप में thisArg
की Array#filter
और ले Set#has
कॉलबैक के रूप में।
function intersection(a, b) {
return a.filter(Set.prototype.has, new Set(b));
}
console.log(intersection([1, 2, 3], [2, 3, 4, 5]));
एक छोटी सी छोटी को यहाँ ( फ़िल्टर / इंडेक्सऑफ़ सॉल्यूशन ) के लिए एक छोटा ट्वीक , अर्थात् जावास्क्रिप्ट ऑब्जेक्ट का उपयोग करके किसी एक सरणियों में मानों का एक इंडेक्स बनाते हुए, इसे O (N * M) से "संभवतः" रैखिक समय तक कम कर देगा। source1 सोर्स 2
function intersect(a, b) {
var aa = {};
a.forEach(function(v) { aa[v]=1; });
return b.filter(function(v) { return v in aa; });
}
यह सबसे सरल समाधान नहीं है (यह फ़िल्टर + इंडेक्सऑफ़ की तुलना में अधिक कोड है ), और न ही यह बहुत तेज़ है (संभवत: intersect_safe () की तुलना में एक स्थिर कारक द्वारा धीमा है ), लेकिन एक बहुत अच्छा संतुलन की तरह लगता है। यह बहुत सरल पक्ष पर है, जबकि अच्छा प्रदर्शन प्रदान करता है, और इसके लिए पूर्व-सॉर्ट किए गए इनपुट की आवश्यकता नहीं होती है।
एक और अनुक्रमित दृष्टिकोण किसी भी संख्या में सरणियों को एक साथ संसाधित करने में सक्षम है:
// Calculate intersection of multiple array or object values.
function intersect (arrList) {
var arrLength = Object.keys(arrList).length;
// (Also accepts regular objects as input)
var index = {};
for (var i in arrList) {
for (var j in arrList[i]) {
var v = arrList[i][j];
if (index[v] === undefined) index[v] = 0;
index[v]++;
};
};
var retv = [];
for (var i in index) {
if (index[i] == arrLength) retv.push(i);
};
return retv;
};
यह केवल उन मूल्यों के लिए काम करता है, जिन्हें स्ट्रिंग्स के रूप में मूल्यांकन किया जा सकता है और आपको उन्हें एक सरणी के रूप में पास करना चाहिए:
intersect ([arr1, arr2, arr3...]);
... लेकिन यह पारदर्शी रूप से वस्तुओं को पैरामीटर के रूप में स्वीकार करता है या किसी भी तत्व को प्रतिच्छेद करने के लिए (हमेशा सामान्य मानों की सरणी लौटाता है)। उदाहरण:
intersect ({foo: [1, 2, 3, 4], bar: {a: 2, j:4}}); // [2, 4]
intersect ([{x: "hello", y: "world"}, ["hello", "user"]]); // ["hello"]
संपादित करें: मैंने अभी देखा कि यह एक तरह से थोड़ा छोटी गाड़ी है।
अर्थात: मैंने यह सोचकर कोडित किया है कि इनपुट सरणियों में स्वयं पुनरावृत्ति नहीं हो सकती (जैसा कि उदाहरण दिया गया है)।
लेकिन यदि इनपुट सरणियों में पुनरावृत्ति होती है, तो यह गलत परिणाम देगा। उदाहरण (नीचे कार्यान्वयन का उपयोग करके):
intersect ([[1, 3, 4, 6, 3], [1, 8, 99]]);
// Expected: [ '1' ]
// Actual: [ '1', '3' ]
सौभाग्य से बस दूसरे स्तर के अनुक्रमण को जोड़कर इसे ठीक करना आसान है। अर्थात्:
परिवर्तन:
if (index[v] === undefined) index[v] = 0;
index[v]++;
द्वारा:
if (index[v] === undefined) index[v] = {};
index[v][i] = true; // Mark as present in i input.
...तथा:
if (index[i] == arrLength) retv.push(i);
द्वारा:
if (Object.keys(index[i]).length == arrLength) retv.push(i);
पूरा उदाहरण:
// Calculate intersection of multiple array or object values.
function intersect (arrList) {
var arrLength = Object.keys(arrList).length;
// (Also accepts regular objects as input)
var index = {};
for (var i in arrList) {
for (var j in arrList[i]) {
var v = arrList[i][j];
if (index[v] === undefined) index[v] = {};
index[v][i] = true; // Mark as present in i input.
};
};
var retv = [];
for (var i in index) {
if (Object.keys(index[i]).length == arrLength) retv.push(i);
};
return retv;
};
intersect ([[1, 3, 4, 6, 3], [1, 8, 99]]); // [ '1' ]
var v =
लाइन जोड़ने के बाद if (typeof v == 'function') continue;
और यह परिणामों में फ़ंक्शन जोड़ना छोड़ देगा। धन्यवाद!
if (typeof v == 'function')
, तो हम v.toString()
इंडेक्स की कुंजी के रूप में इसके स्ट्रिफ़िकेशन ( ) का उपयोग कर सकते हैं । लेकिन, हमें इसे बरकरार रखने के लिए कुछ करने की ज़रूरत है।) ऐसा करने का सबसे आसान तरीका बस मूल फ़ंक्शन को एक साधारण बूलियन सही मान के बजाय मान के रूप में असाइन करना है। लेकिन, उस स्थिति में, इस स्थिति का पता लगाने और सही मान (फ़ंक्शन) को पुनर्स्थापित करने के लिए नवीनतम डिंडेक्सटन को भी बदल दिया जाना चाहिए।
आप (IE को छोड़कर सभी ब्राउज़रों के लिए) का उपयोग कर सकते हैं:
const intersection = array1.filter(element => array2.includes(element));
या IE के लिए:
const intersection = array1.filter(element => array2.indexOf(element) !== -1);
आपके डेटा पर कुछ प्रतिबंधों के साथ, आप इसे रैखिक में कर सकते हैं समय !
के लिए धनात्मक पूर्णांक : एक "देखा / नहीं देखा" बूलियन के लिए एक सरणी मान मैप का उपयोग करें।
function intersectIntegers(array1,array2) {
var seen=[],
result=[];
for (var i = 0; i < array1.length; i++) {
seen[array1[i]] = true;
}
for (var i = 0; i < array2.length; i++) {
if ( seen[array2[i]])
result.push(array2[i]);
}
return result;
}
वस्तुओं के लिए एक समान तकनीक है : एक डमी कुंजी लें, इसे array1 में प्रत्येक तत्व के लिए "सही" पर सेट करें, फिर array2 के तत्वों में इस कुंजी को देखें। काम पूरा होने पर साफ करें।
function intersectObjects(array1,array2) {
var result=[];
var key="tmpKey_intersect"
for (var i = 0; i < array1.length; i++) {
array1[i][key] = true;
}
for (var i = 0; i < array2.length; i++) {
if (array2[i][key])
result.push(array2[i]);
}
for (var i = 0; i < array1.length; i++) {
delete array1[i][key];
}
return result;
}
बेशक आपको यह सुनिश्चित करने की आवश्यकता है कि कुंजी पहले प्रकट नहीं हुई थी, अन्यथा आप अपना डेटा नष्ट कर देंगे ...
जो मेरे लिए सबसे अच्छा काम कर रहा है, मैं उसमें योगदान दूंगा:
if (!Array.prototype.intersect){
Array.prototype.intersect = function (arr1) {
var r = [], o = {}, l = this.length, i, v;
for (i = 0; i < l; i++) {
o[this[i]] = true;
}
l = arr1.length;
for (i = 0; i < l; i++) {
v = arr1[i];
if (v in o) {
r.push(v);
}
}
return r;
};
}
IE 9.0 के लिए "indexOf", क्रोम, फ़ायरफ़ॉक्स, ओपेरा,
function intersection(a,b){
var rs = [], x = a.length;
while (x--) b.indexOf(a[x])!=-1 && rs.push(a[x]);
return rs.sort();
}
intersection([1,2,3], [2,3,4,5]);
//Result: [2,3]
'use strict'
// Example 1
function intersection(a1, a2) {
return a1.filter(x => a2.indexOf(x) > -1)
}
// Example 2 (prototype function)
Array.prototype.intersection = function(arr) {
return this.filter(x => arr.indexOf(x) > -1)
}
const a1 = [1, 2, 3]
const a2 = [2, 3, 4, 5]
console.log(intersection(a1, a2))
console.log(a1.intersection(a2))
एक कार्यात्मक दृष्टिकोण को साइड इफेक्ट्स के बिना केवल शुद्ध कार्यों का उपयोग करने पर विचार करना चाहिए, जिनमें से प्रत्येक केवल एक नौकरी से संबंधित है।
इन प्रतिबंधों में शामिल कार्यों की रचनाशीलता और पुन: प्रयोज्यता को बढ़ाया जाता है।
// small, reusable auxiliary functions
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
const apply = f => x => f(x);
// intersection
const intersect = xs => ys => {
const zs = createSet(ys);
return filter(x => zs.has(x)
? true
: false
) (xs);
};
// mock data
const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];
// run it
console.log( intersect(xs) (ys) );
कृपया ध्यान दें कि मूल Set
प्रकार का उपयोग किया जाता है, जिसमें एक लाभप्रद लुकअप प्रदर्शन होता है।
स्पष्ट रूप से पहले से बार-बार होने वाली वस्तुओं Array
को संरक्षित किया जाता है, जबकि दूसरे Array
को डी-डुप्लिकेट किया जाता है। यह वांछित व्यवहार हो सकता है या नहीं भी हो सकता है। यदि आपको एक अद्वितीय परिणाम की आवश्यकता है, तो बस dedupe
पहले तर्क पर लागू हों :
// auxiliary functions
const apply = f => x => f(x);
const comp = f => g => x => f(g(x));
const afrom = apply(Array.from);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
// intersection
const intersect = xs => ys => {
const zs = createSet(ys);
return filter(x => zs.has(x)
? true
: false
) (xs);
};
// de-duplication
const dedupe = comp(afrom) (createSet);
// mock data
const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];
// unique result
console.log( intersect(dedupe(xs)) (ys) );
Array
रोंआप में से एक मनमाने ढंग से संख्या के चौराहे की गणना करना चाहते हैं Array
रों सिर्फ रचना intersect
के साथ foldl
। यहाँ एक सुविधा समारोह है:
// auxiliary functions
const apply = f => x => f(x);
const uncurry = f => (x, y) => f(x) (y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc);
// intersection
const intersect = xs => ys => {
const zs = createSet(ys);
return filter(x => zs.has(x)
? true
: false
) (xs);
};
// intersection of an arbitrarily number of Arrays
const intersectn = (head, ...tail) => foldl(intersect) (head) (tail);
// mock data
const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];
const zs = [0,1,2,3,4,5,6];
// run
console.log( intersectn(xs, ys, zs) );
(expr ? true : false)
निरर्थक। उपयोग सिर्फ expr
अगर वास्तविक बूलियन्स आवश्यक नहीं हैं, बस truthy / falsy।
सरलता के लिए:
// Usage
const intersection = allLists
.reduce(intersect, allValues)
.reduce(removeDuplicates, []);
// Implementation
const intersect = (intersection, list) =>
intersection.filter(item =>
list.some(x => x === item));
const removeDuplicates = (uniques, item) =>
uniques.includes(item) ? uniques : uniques.concat(item);
// Example Data
const somePeople = [bob, doug, jill];
const otherPeople = [sarah, bob, jill];
const morePeople = [jack, jill];
const allPeople = [...somePeople, ...otherPeople, ...morePeople];
const allGroups = [somePeople, otherPeople, morePeople];
// Example Usage
const intersection = allGroups
.reduce(intersect, allPeople)
.reduce(removeDuplicates, []);
intersection; // [jill]
लाभ:
कमियां:
आप इसे 3D इंजन या कर्नेल कार्य के लिए उपयोग नहीं करना चाहेंगे, लेकिन यदि आपको ईवेंट-आधारित ऐप में इसे चलाने में समस्या आ रही है, तो आपके डिज़ाइन में बड़ी समस्याएं हैं।
.reduce
एक नक्शा बनाने के लिए, और .filter
चौराहे को खोजने के लिए। delete
भीतर .filter
की अनुमति देता है हमें दूसरी सरणी के इलाज के लिए जैसे कि यह एक अद्वितीय सेट है।
function intersection (a, b) {
var seen = a.reduce(function (h, k) {
h[k] = true;
return h;
}, {});
return b.filter(function (k) {
var exists = seen[k];
delete seen[k];
return exists;
});
}
मैं इस दृष्टिकोण के बारे में तर्क करने के लिए बहुत आसान लगता है। यह निरंतर समय में प्रदर्शन करता है।
यह शायद सबसे सरल है, इसके अलावा list1.filter (n => list2.includes (n))
var list1 = ['bread', 'ice cream', 'cereals', 'strawberry', 'chocolate']
var list2 = ['bread', 'cherry', 'ice cream', 'oats']
function check_common(list1, list2){
list3 = []
for (let i=0; i<list1.length; i++){
for (let j=0; j<list2.length; j++){
if (list1[i] === list2[j]){
list3.push(list1[i]);
}
}
}
return list3
}
check_common(list1, list2) // ["bread", "ice cream"]
यदि आपको कई सरणियों को समाहित करने की आवश्यकता है, तो:
const intersect = (a, b, ...rest) => {
if (rest.length === 0) return [...new Set(a)].filter(x => new Set(b).has(x));
return intersect(a, intersect(b, ...rest));
};
console.log(intersect([1,2,3,4,5], [1,2], [1, 2, 3,4,5], [2, 10, 1])) // [1,2]
ES6 शैली सरल तरीका है।
const intersection = (a, b) => {
const s = new Set(b);
return a.filter(x => s.has(x));
};
उदाहरण:
intersection([1, 2, 3], [4, 3, 2]); // [2, 3]
मैंने एक इंटेसेशन फ़ंक्शन लिखा है जो उन वस्तुओं की विशेष संपत्ति के आधार पर ऑब्जेक्ट्स की सरणी के प्रतिच्छेदन का भी पता लगा सकता है।
उदाहरण के लिए,
if arr1 = [{id: 10}, {id: 20}]
and arr2 = [{id: 20}, {id: 25}]
और हम चाहते हैं कि id
संपत्ति के आधार पर प्रतिच्छेदन हो , फिर आउटपुट होना चाहिए:
[{id: 20}]
जैसे, उसी के लिए फ़ंक्शन (नोट: ES6 कोड) है:
const intersect = (arr1, arr2, accessors = [v => v, v => v]) => {
const [fn1, fn2] = accessors;
const set = new Set(arr2.map(v => fn2(v)));
return arr1.filter(value => set.has(fn1(value)));
};
और आप फ़ंक्शन को इस रूप में कह सकते हैं:
intersect(arr1, arr2, [elem => elem.id, elem => elem.id])
यह भी ध्यान दें: यह फ़ंक्शन चौराहे को पाता है कि पहली सरणी पर विचार प्राथमिक सरणी है और इस प्रकार चौराहे का परिणाम प्राथमिक सरणी होगा।
सोचें कि यह तेजी से O (array1 + array2) समय मानकर चल रहा है। map () (~) है ~ O (1)। गलत होने पर कृपया मुझे सुधारें।
const intersection = (a1, a2) => {
let map = new Map();
let result = []
for (let i of a1) {
if (!map.has(i)) map.set(i, true);
}
for (let i of a2) {
if (map.has(i)) result.push(i)
}
return result;
}
यहाँ underscore.js कार्यान्वयन है:
_.intersection = function(array) {
if (array == null) return [];
var result = [];
var argsLength = arguments.length;
for (var i = 0, length = array.length; i < length; i++) {
var item = array[i];
if (_.contains(result, item)) continue;
for (var j = 1; j < argsLength; j++) {
if (!_.contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
};
स्रोत: http://underscorejs.org/docs/underscore.html#section-62