El código más simple para la intersección de matrices en javascript

Resuelto Peter asked hace 14 años • 40 respuestas

¿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]
Peter avatar Dec 11 '09 10:12 Peter
Aceptado

Utilice una combinación de Array.prototype.filtery Array.prototype.includes:

const filteredArray = array1.filter(value => array2.includes(value));

Para navegadores más antiguos, con Array.prototype.indexOfy sin función de flecha:

var filteredArray = array1.filter(function(n) {
    return array2.indexOf(n) !== -1;
});

¡NÓTESE BIEN! Tanto .includesy .indexOfcompara 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.someen su lugar.

Anon. avatar Dec 11 '2009 03:12 Anon.

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;
}
atk avatar Dec 11 '2009 03:12 atk

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]).sizese evalúa como 3.

nbarbosa avatar May 05 '2016 03:05 nbarbosa