Búsqueda de sitios web

javascript - Filtrar un array en Typescript usando programación funcional [filter, map, some, reduce, etc]


Estoy tratando de trabajar con programación funcional

Tengo dos arreglos

arr1=[{prodId:2}{prodId:4}]

arr2=[{id:1, name:"Test1"},
      {id:2, name:"Test2"},
      {id:3, name:"Test3"},
      {id:4, name:"Test4"},
      {id:5, name:"Test5"}]

usando una combinación de

funciones filter, map, some, reduce

Quiero extraer elementos de arr2

where arr2.id === arr1.prodId 

mi arreglo de salida sería:

  [{id:2, name:"Test2"},
  {id:4, name:"Test4"}]

Estoy intentando evitar forEach y usar programación funcional.

Respuesta #1

Deberías usar el método filter en combinación con includes y map.

let arr1=[{prodId:2},{prodId:4}], arr2=[{id:1, name:"Test1"}, {id:2, name:"Test2"}, {id:3, name:"Test3"}, {id:4, name:"Test4"}, {id:5, name:"Test5"}];
let ids = arr1.map(({prodId}) => prodId);
let result = arr2.filter(({id}) => ids.includes(id));
console.log(result);

Otro enfoque es usar el método some.

let arr1=[{prodId:2},{prodId:4}], arr2=[{id:1, name:"Test1"}, {id:2, name:"Test2"}, {id:3, name:"Test3"}, {id:4, name:"Test4"}, {id:5, name:"Test5"}];

let result = arr2.filter(({id}) => arr1.some(({prodId}) => prodId == id));
console.log(result);

Respuesta #2

Las soluciones que utilizan .includes, .find o .some son operaciones de arrays y tienen un costo de tiempo lineal. Cuando se usan dentro de .filter, otra operación de tiempo lineal, el resultado es un cálculo de tiempo cuadrático. Si las listas de entrada son grandes, este impacto no es insignificante.

En su lugar, primero recopila los ids para coincidir en un Set y luego aprovecha la búsqueda en tiempo constante en el filter -

const arr1 = 
  [ { prodId: 2 }
  , { prodId: 4 }
  ]

const arr2 =
  [ { id:1, name:"Test1" }
  , { id:2, name:"Test2" }
  , { id:3, name:"Test3" }
  , { id:4, name:"Test4" }
  , { id:5, name:"Test5" }
  ]
      
const find = (whitelist, list) =>
{ const ids =
    new Set (whitelist.map(x => x.prodId)) // create a set
    
  return list.filter(x => ids.has(x.id)) // Set#has uses constant time
}

console.log(find(arr1,arr2))
// [ { id: 2, name: "Test2" }, { id: 4, name: "Test4" } ]