Javascript'te dizi kavşaklarını uygulamak için en basit, kütüphane içermeyen kod nedir? yazmak istiyorum
intersection([1,2,3], [2,3,4,5])
ve Al
[2, 3]
break
için Simple js loops
~ 10M artar ops / sn
Javascript'te dizi kavşaklarını uygulamak için en basit, kütüphane içermeyen kod nedir? yazmak istiyorum
intersection([1,2,3], [2,3,4,5])
ve Al
[2, 3]
break
için Simple js loops
~ 10M artar ops / sn
Yanıtlar:
Kombinasyonunu kullanın Array.prototype.filter
ve Array.prototype.indexOf
:
array1.filter(value => -1 !== array2.indexOf(value))
Veya yorumlarda önerilen vrugtehagel'inArray.prototype.includes
daha basit kod için daha yenisini kullanabilirsiniz :
array1.filter(value => array2.includes(value))
Daha eski tarayıcılar için:
array1.filter(function(n) {
return array2.indexOf(n) !== -1;
});
intersection([1,2,1,1,3], [1])
döner [1, 1, 1]
. Sadece geri dönmemeli [1]
mi?
array2.indexOf(n) != -1
de yazabilirsiniz array2.includes(n)
.
Yıkıcı en basit görünüyor, özellikle de girdinin sıralandığını varsayabilirsek:
/* 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;
}
Tahribatsız saçlar daha karmaşık olmalı, çünkü endeksleri takip etmeliyiz:
/* 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
Dizilerde bir yöntem değil, bir özellik. 'De tanımlanmamış bir değişken i
var result.push(a[i]);
. Son olarak, bu sadece genel durumda işe yaramaz: >
operatöre göre ikisinden de daha büyük olmayan iki nesne mutlaka eşit değildir. intersect_safe( [ {} ], [ {} ] )
örneğin, (daha önce belirtilen hatalar düzeltildikten sonra) bir öğeye sahip olan ve açıkça yanlış olan bir dizi verecektir.
.slice(0)
Dizileri intersect_safe
izlemek yerine dizinin bir kopyasını oluşturmak için de kullanabilirsiniz .
Ortamınız ECMAScript 6 Set'i destekliyorsa , basit ve sözde verimli (spesifikasyon bağlantısına bakın) bir yol:
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);
}
Daha kısa, ancak daha az okunabilir (ek kavşak oluşturmadan da Set
):
function intersect(a, b) {
return [...new Set(a)].filter(x => new Set(b).has(x));
}
Yeni kaçınmak Set
gelen b
her zaman:
function intersect(a, b) {
var setB = new Set(b);
return [...new Set(a)].filter(x => setB.has(x));
}
Kümeleri kullanırken yalnızca farklı değerler elde edeceğinizi ve dolayısıyla new Set[1,2,3,3].size
değerlendirildiğinizi unutmayın 3
.
[...setA]
sözdizimi nedir? Özel bir tür javascript işlemi?
x => new Set(b).has(x)
ok işlevi her yürütüldüğünde b
bir kümeye dönüşmüyor mu? Muhtemelen bu seti bir değişkene kaydetmelisiniz.
Underscore.js veya lodash.js kullanma
_.intersection( [0,345,324] , [1,0,324] ) // gives [0,324]
ES6 açısından katkım. Genelde, bağımsız değişken olarak sağlanan sınırsız sayıda dizinin bulunduğu bir dizinin kesişimini bulur.
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]]
ve sonra uygular .reduce()
. İlk [0,1,2,3,4,5,6,7,8,9].filter( e => [0,2,4,6,8].includes(e)
operasyon gerçekleştirilir ve sonuç yeni hale gelir p
ve c
olur [4,5,6,7]
sonraki sırayla ve artık kalmayıncaya kadar yukarı böylece devam c
bırakılır.
prototype
Gereksiz yere değişiklik yapmayın .
// 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]));
Yukarıda, büyük girdiler üzerindeki diğer uygulamalardan daha iyi performans gösteren kısa özümü öneririm. Küçük girişlerdeki performans önemliyse, aşağıdaki alternatifleri kontrol edin.
Alternatifler ve performans karşılaştırması:
Alternatif uygulamalar için aşağıdaki snippet'e bakın ve performans karşılaştırmaları için https://jsperf.com/array-intersection-comparison adresini kontrol edin .
Firefox 53 sonuçları:
Büyük dizilerde Ops / sn (10.000 eleman):
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
Küçük dizilerde Ops / sn (100 eleman):
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])
döner [2, 2, 3]
.
a.filter(b.includes)
. Çok daha hızlı çalışmalıdır (işlev yükseltmenizle aynı).
İlişkisel dizileri kullanmaya ne dersiniz?
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;
}
Düzenle:
// 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;
yerine d[b[j]] = true;
( i
değil j
). Ancak düzenleme 6 karakter gerektirir.
Böyle bir şey, Ama iyi test değil.
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]));
PS: Sadece Sayılar ve Normal Dizeler için tasarlanmış algoritma, arbitary nesne dizilerinin kesişimi çalışmayabilir.
@ Atk uygulamasının sıralı ilkel diziler için uygulama performansı .shift yerine .pop kullanılarak iyileştirilebilir.
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 kullanarak bir ölçüt oluşturdum . .Pop kullanmak yaklaşık üç kat daha hızlı.
a[aLast] > b[bLast]
, bunun dizelerde çalışacağını unutmayın. a[aLast].localeCompare(b[bLast]) > 0
else if
.pop
O (1) ve .shift()
O (n)
JQuery kullanma :
var a = [1,2,3];
var b = [2,3,4,5];
var c = $(b).not($(b).not(a));
alert(c);
c = $(b).filter(a);
, ancak belgelerin yalnızca öğeler için çalıştığını belirttiği için bu tür dizi manipülasyonu için jQuery'ye güvenmenizi tavsiye etmem.
Yalnızca dizeleri veya sayıları içeren diziler için, diğer yanıtların bazılarına göre sıralama ile bir şeyler yapabilirsiniz. Keyfi nesne dizilerinin genel durumu için, bunu uzun yoldan yapmaktan kaçınabileceğinizi sanmıyorum. Aşağıdakiler, parametre olarak sağlanan herhangi bir dizi dizinin kesişimini verecektir 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
ya da firstArray
tüm referansları güncellememek konusunda fikrimi açıkça değiştirdim . Sabit.
ES2015 ve Setler kullanarak oldukça kısa. Dize gibi Dizi benzeri değerleri kabul eder ve yinelenenleri kaldırır.
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(''));
Bir kullanabilirsiniz Set
olarak thisArg
bir Array#filter
ve almak Set#has
geri arama.
function intersection(a, b) {
return a.filter(Set.prototype.has, new Set(b));
}
console.log(intersection([1, 2, 3], [2, 3, 4, 5]));
JavaScript nesnesini kullanarak dizilerden birinde değerlerin bir dizinini oluşturmak için buradaki en küçük olana ( filter / indexOf çözümü ) küçük bir değişiklik , onu O (N * M) 'den "muhtemelen" doğrusal süreye indirecektir. kaynak1 kaynak2
function intersect(a, b) {
var aa = {};
a.forEach(function(v) { aa[v]=1; });
return b.filter(function(v) { return v in aa; });
}
Bu en basit çözüm değil ( filter + indexOf'dan daha fazla kod ), ne de en hızlı (muhtemelen intersect_safe () ' den daha sabit bir faktör tarafından daha yavaş ), ama oldukça iyi bir denge gibi görünüyor. Bu açık çok iyi bir performans sağlayan ve önceden sıralanmış girdileri gerektirmez iken, basit tarafı.
Herhangi bir sayıda diziyi aynı anda işleyebilen başka bir dizinlenmiş yaklaşım:
// 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;
};
Yalnızca dize olarak değerlendirilebilen değerler için çalışır ve bunları aşağıdaki gibi bir dizi olarak iletmeniz gerekir:
intersect ([arr1, arr2, arr3...]);
... ancak nesneleri parametre olarak veya kesişilecek öğelerin herhangi biri olarak şeffaf olarak kabul eder (her zaman ortak değer dizisi döndürür). Örnekler:
intersect ({foo: [1, 2, 3, 4], bar: {a: 2, j:4}}); // [2, 4]
intersect ([{x: "hello", y: "world"}, ["hello", "user"]]); // ["hello"]
EDIT: Ben sadece, bir bakıma, biraz buggy olduğunu fark ettim.
Yani, girdi dizilerinin kendisinin tekrarlar içeremeyeceğini düşünerek kodladım (verilen örnekte olmadığı gibi).
Ancak girdi dizileri yineleme içeriyorsa, bu yanlış sonuçlar verir. Örnek (aşağıdaki uygulamayı kullanarak):
intersect ([[1, 3, 4, 6, 3], [1, 8, 99]]);
// Expected: [ '1' ]
// Actual: [ '1', '3' ]
Neyse ki, sadece ikinci seviye endeksleme ekleyerek bunu düzeltmek kolaydır. Yani:
Değişiklik:
if (index[v] === undefined) index[v] = 0;
index[v]++;
tarafından:
if (index[v] === undefined) index[v] = {};
index[v][i] = true; // Mark as present in i input.
...ve:
if (index[i] == arrLength) retv.push(i);
tarafından:
if (Object.keys(index[i]).length == arrLength) retv.push(i);
Komple örnek:
// 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 =
satır ekleyin if (typeof v == 'function') continue;
ve sonuçlara işlev ekleme atlar. Teşekkürler!
if (typeof v == 'function')
, o zaman dizesini ( v.toString()
) kullanarak dizin için anahtar olarak kullanabiliriz . bunu yapmak için en kolay yolu bu durumda, son deindexaton da bu durumu tespit etmek ve doğru değeri (fonksiyonu) geri müdahale edilmeli, yerine basit bir mantıksal doğru değerin değer olarak özgün işlevini atamak basitçe Ama..
Şunları kullanabilirsiniz (IE dışındaki tüm tarayıcılar için):
const intersection = array1.filter(element => array2.includes(element));
veya IE için:
const intersection = array1.filter(element => array2.indexOf(element) !== -1);
Verilerinizdeki bazı kısıtlamalarla, bunu doğrusal zamanda yapabilirsiniz!
İçin pozitif tamsayılar : Bir "görülme / görmedim" mantıksala değerlerinin eşlenmesi bir dizi kullanın.
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;
}
Nesneler için benzer bir teknik vardır : kukla bir anahtar alın, dizi1'deki her öğe için "true" olarak ayarlayın, sonra dizi2 öğelerinde bu anahtarı arayın. İşiniz bittiğinde temizleyin.
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;
}
Tabii ki anahtarın daha önce görünmediğinden emin olmalısınız, aksi takdirde verilerinizi yok edeceksiniz ...
Benim için en iyi olana katkıda bulunacağım:
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, chrome, firefox, opera, "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))
İşlevsel bir yaklaşım, her biri sadece tek bir işle ilgili olan sadece yan etkileri olmayan saf işlevleri kullanmayı düşünmelidir.
Bu kısıtlamalar, ilgili işlevlerin birleştirilebilirliğini ve tekrar kullanılabilirliğini artırır.
// 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
Avantajlı bir arama performansına sahip yerel türün kullanıldığını lütfen unutmayın .
Birinciden defalarca tekrarlanan öğeler Array
korunurken, ikincisi Array
de çoğaltılır. Bu istenen davranış olabilir veya olmayabilir. Benzersiz bir sonuca ihtiyacınız varsa sadece dedupe
ilk argümana başvurun :
// 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
s'nin kesişimini hesaplayınEğer bir keyfi sayıda kavşak hesaplamak istiyorsanız Array
s sadece beste intersect
ile foldl
. İşte bir kolaylık işlevi:
// 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)
gereksizdir. Sadece expr
gerçek booleanlara ihtiyaç duyulmuyorsa, sadece doğru / falsili kullanın.
Basitlik için:
// 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]
Yararları:
Dezavantajları:
Bunu 3D motor veya çekirdek çalışması için kullanmak istemezsiniz, ancak bunu olay tabanlı bir uygulamada çalıştırmakta sorun yaşıyorsanız, tasarımınızın daha büyük sorunları vardır.
.reduce
bir harita oluşturmak .filter
ve kavşağı bulmak. delete
içinde .filter
ikinci diziye benzersiz bir küme gibi davranmamızı sağlar
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;
});
}
Bu yaklaşımı akıl yürütmek oldukça kolay buluyorum. Sabit zamanda çalışır.
Bu muhtemelen list1.filter (n => list2.includes (n)) dışında en basit olanıdır
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"]
Kesişen birden çok diziyi ele almanız gerekiyorsa:
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 tarzı basit bir yol.
const intersection = (a, b) => {
const s = new Set(b);
return a.filter(x => s.has(x));
};
Misal:
intersection([1, 2, 3], [4, 3, 2]); // [2, 3]
Hatta bu nesnelerin belirli özelliklerine dayalı nesne dizisinin kesişimini algılayabilir bir intesection fonksiyonu yazdım.
Örneğin,
if arr1 = [{id: 10}, {id: 20}]
and arr2 = [{id: 20}, {id: 25}]
ve id
mülke dayalı bir kavşak istiyoruz , o zaman çıktı şöyle olmalıdır:
[{id: 20}]
Aynı şekilde, aynı işlev (not: ES6 kodu):
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)));
};
ve işlevi şu şekilde çağırabilirsiniz:
intersect(arr1, arr2, [elem => elem.id, elem => elem.id])
Ayrıca not: bu işlev, ilk dizi birincil dizi olduğu için kesişim bulur ve böylece kesişim sonucu birincil dizinin işlevi olacaktır.
Map.has () ~ O (1) olduğunu varsayarak O (dizi1 + dizi2) zamanıyla bunun daha hızlı olacağını düşünün. Yanlışsa lütfen beni düzeltin.
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;
}
İşte underscore.js uygulaması:
_.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;
};
Kaynak: http://underscorejs.org/docs/underscore.html#section-62