4
votes

Recherche d'intersection dans plusieurs tableaux

J'essaye de trouver les valeurs qui se croisent dans plusieurs tableaux, qui se trouvent dans un objet comme suit:

object = {
  filterA: ["1","2","3","4"],
  filterB: ["2","5","6","7"],
  filterN: ["2","4","7"]
}

L'objet peut contenir plusieurs tableaux et le nom des clés peut varier. Dans l'objet décrit, je n'ai besoin que de "2" pour être renvoyé.

J'ai essayé de construire sur cette réponse: Intersection de plusieurs tableaux en javascript mais je n'ai pas pu le comprendre, car il utilise des variables statiques (a, b, c) pour l'exemple. S'il y a un moyen de le faire avec lodash, ce sera apprécié, mais javascript vanille dans ES 5 fera également l'affaire!


1 commentaires

7 Réponses :


1
votes

Itérer sur la première valeur de propriété (tableau) et filtrer en comparant avec la valeur de propriété restante.

let object = {
  filterA: ["1", "2", "3", "4"],
  filterB: ["2", "5", "6", "7"],
  filterN: ["2", "4", "7"]
};


let arr = Object.values(object);

let res = arr[0].filter(v => arr.slice(1).every(a => a.includes(v)));


console.log(res)

// get property values(arraya as array)
let arr = Object.values(object);


let res = arr[0]
  // iterate over first array
  // check value present in remaining object values(arrays)
  .filter(v => arr.slice(1).every(a => a.includes(v)));


3 commentaires

Salut @Pranav pouvez-vous me donner une version ES5, sans les fonctions fléchées


@PresianNedyalkov: bien sûr


@PresianNedyalkov arr [0] .filter (function (v) {return arr.slice (1) .every (function (a) {return a.includes (v)})});



0
votes
object = {
  filterA: ["1","2","3","4"],
  filterB: ["2","5","6","7"],
  filterN: ["2","4","7"]
}

let arr = Object.values(object);

let res = arr[0].filter(v => arr.slice(1).every(a => a.includes(v)));


console.log(res)

2 commentaires

Salut @umer, pouvez-vous me donner une solution ES5 (pas de fonctions fléchées)


essayez ceci: arr [0] .filter (function (v) {return arr.slice (1) .every (function (a) {return a.includes (v)})});



4
votes

Vous pouvez obtenir les valeurs et prendre un Définissez et filtrez avec Set # has .

var object = { filterA: ["1", "2", "3", "4"], filterB: ["2", "5", "6", "7"], filterN: ["2", "4", "7"] },
    result = Object
        .values(object)
        .reduce((a, b) => b.filter(Set.prototype.has, new Set(a)));

console.log(result);


2 commentaires

Grande utilisation du this du filtre.


Je finis par utiliser cette solution, après avoir vérifié les valeurs de la solution lodash, qui était initialement ok mais après un certain temps a produit des valeurs erronées pour une raison quelconque. J'ai transpilé la réponse avec babel en ligne ( babeljs.io/repl ), car le système que j'utilise ne le fait pas transpile es6.



1
votes

reduction fera le travail pour vous. Consultez mon code ci-dessous.

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
var object = {
  filterA: ["1","2","3","4"],
  filterB: ["2","5","6","7"],
  filterN: ["2","4","7"]
}

var res = Object.values(object).reduce(function (acc, array) {
  return _.intersection(acc, array)
})

console.log(res)


0 commentaires

1
votes

J'ai une approche simple en une seule ligne:

const res = Object.values(object).reduce(function (a, b) { 
  return a.filter(function(i) {
    //return b.includes(i);
    return b.indexOf(i) >= 0;
  });
});

console.log(res);

Mais comme vous le voulez dans la version ES5 (ECMAScript 2009), cela signifie pas de fonctions fléchées, pas d'includes () et pas d'utilisation d'objets Set.

const res = Object.values(object).reduce((a, b) => a.filter(i => b.includes(i)))


4 commentaires

Salut @wentjun, pouvez-vous me donner une solution ES5 (pas de fonctions fléchées)


includes n'est probablement pas disponible dans l'environnement ES5 sans polyfill


Ah oui! Merci @charlietfl, j'ai remplacé includes par indexOf ()> = 0 pour vérifier si l'élément existe dans le tableau.


@PresianNedyalkov Très bien, je l'ai modifié une fois de plus



0
votes

_.intersection () de Lodash peut gérer plusieurs tableaux. Vous pouvez créer une fonction avec _.flow () qui obtient un tableau de tableaux de l'objet avec _.values ​​() et calcule l'intersection en utilisant _.intersection () avec _.spread () .

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
const { flow, values, spread, intersection } = _

const fn = flow(
  values, // get the arrays
  spread(_.intersection) // spread into intersection
)

const object = {
  filterA: ["1","2","3","4"],
  filterB: ["2","5","6","7"],
  filterN: ["2","4","7"]
}

const result = fn(object)

console.log(result)


0 commentaires

0
votes
let arrayOfComparisonArrays = [[1,2,3,4,5], [5,3], [1,3,4,5], [5,1,3]]
let intersectionArray

intersectionArray = arrayOfComparisonArrays.reduce((lastArray, nextArray)=>{
    let intersection = lastArray.filter(x => nextArray.includes(x))
    return intersection
})

//intersectionArray: [ 3, 5 ] 

0 commentaires