El código más simple para la intersección de matrices en javascript
¿Cuál es el código más simple y sin biblioteca para implementar intersecciones de matrices en javascript? Quiero escribir
intersection([1,2,3], [2,3,4,5])
y obten
[2, 3]
Utilice una combinación de Array.prototype.filter
y Array.prototype.includes
:
const filteredArray = array1.filter(value => array2.includes(value));
Para navegadores más antiguos, con Array.prototype.indexOf
y sin función de flecha:
var filteredArray = array1.filter(function(n) {
return array2.indexOf(n) !== -1;
});
¡NÓTESE BIEN! Tanto .includes
y .indexOf
compara internamente elementos en la matriz usando ===
, por lo que si la matriz contiene objetos, solo comparará referencias de objetos (no su contenido). Si desea especificar su propia lógica de comparación, utilice Array.prototype.some
en su lugar.
Destructivo parece lo más simple, especialmente si podemos asumir que la entrada está ordenada:
/* 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;
}
Lo no destructivo tiene que ser un poco más complicado, ya que tenemos que realizar un seguimiento de los índices:
/* 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;
}
Si su entorno admite ECMAScript 6 Set , una forma simple y supuestamente eficiente (consulte el enlace de especificación):
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);
}
Más corto, pero menos legible (también sin crear la intersección adicional Set
):
function intersect(a, b) {
var setB = new Set(b);
return [...new Set(a)].filter(x => setB.has(x));
}
Tenga en cuenta que cuando utilice conjuntos solo obtendrá valores distintos, por lo que new Set([1, 2, 3, 3]).size
se evalúa como 3
.