Vous avez un tableau de tableaux comme celui-ci:
let final = [] for (let i=0; i<arr.length; i++) { let arr1 = i==0?arr:arr.slice(i) let final1 = arr1.reduce((acc,x)=> { acc = acc[0].key==x[0].key?acc.concat(x):acc return acc }) arr1.length>1&&final.push(final1) }
Je dois obtenir ce arr
mais avec des tableaux groupés avec la même valeur "clé" du premier élément donc ça ressemblera à:
let arr = [ [ {"key":2, "other":123}, {"key":2, "other":222} ], [ {"key":3, "other":0} ], [ [ {"key":1, "other":11}, {"key":1, "other":23} ], [ {"key":1, "other":22} ] ], ]
J'ai essayé d'utiliser la fonction de réduction, mais le résultat était totalement différent.
let arr = [ [ {"key":2, "other":123}, {"key":2, "other":222} ], [ {"key":3, "other":0} ], [ {"key":1, "other":11}, {"key":1, "other":23} ], [ {"key":1, "other":22} ] ]
Dans ce code, le problème est qu'il compare arr [1] avec arr [2], arr [3] puis à nouveau arr [2] avec arr [3] et le regroupe (même si arr [1] .key et arr [2] .key et arr [3] .key sont identiques) Pouvez-vous donner quelques conseils ou donner la fonction finale pour faire cela?
p>
4 Réponses :
Je pense que vous voulez quelque chose comme ça, essayez d'exécuter l'extrait de code
let arr = [ [ { "key": 2 }, { "key": 2 } ], [ { "key": 3 } ], [ { "key": 1 }, { "key": 1 } ], [ { "key": 1 } ] ] let result = arr.reduce((res, array) => { array.forEach((value, index) => { const obj = res.find(a => { return !!a.find(({key}) => { return key === value.key }) }) if (obj) { obj.push(value) } else { res.push([value]) } }) return res; }, []) console.log(result);
Créez l'objet de clés
avec son décompte. Ensuite, vous pouvez filtrer les clés qui sont présentes plusieurs fois i: e (count> = 2)
. Ensuite, parcourez votre tableau d'entrée en utilisant reduction
et voyez qu'il est présent dans les clés du tableau filtré, si oui, insérez un tableau séparé et l'autre est accu
. Ensuite, fusionnez les deux tableaux en un seul.
let input = [ [ {"key":2, "other":123}, {"key":2, "other":222} ], [ {"key":3, "other":0} ], [ {"key":1, "other":11}, {"key":1, "other":23} ], [ {"key":1, "other":22} ] ]; // keys with unique key and its count. filter whose count are greater than two. const groupByArrKeysOccurence = input.reduce((accu, arr) => { const key = arr[0].key; accu[key] = (accu[key] || 0) + 1; return accu; }, {}); const filteredKeys = Object.entries(groupByArrKeysOccurence).filter(([_, val]) => val > 1).map(([key, _]) => Number(key)); const multipleArrOccurenceKeys = []; const singleArrOccurenceKeys = input.reduce((accu, arr) => { const isKey = arr.some(({key}) => filteredKeys.includes(key)); if(isKey) { multipleArrOccurenceKeys.push(arr); } else { accu.push(arr); } return accu; }, []); console.log([...singleArrOccurenceKeys, multipleArrOccurenceKeys]);
Cela fonctionne avec l'exemple, cependant si nous modifions le premier tableau du tableau d'entrée de [{"key": 2, "other": 123}, {"key": 2, "other": 222}] à [{"key ": 3," other ": 123}, {" key ": 3," other ": 222}], la longueur finale du tableau doit être 2, le premier tableau avec key = 3 et le second avec key = 1
Cette solution ne produit pas le résultat exact que vous recherchez, mais elle est agréable et propre. Le résultat souhaité vous posera très probablement des problèmes à l'avenir, car certains éléments sont davantage imbriqués que d'autres.
Cette réponse suppose que chaque tableau a toujours au moins un élément, car la question est de regrouper par le clé du premier élément.
let arr = [[{"key":2, "other":123}, {"key":2, "other":222}], [{"key":3, "other":0}], [{"key":1, "other":11}, {"key":1, "other":23}], [{"key":1, "other":22}]]; let groups = {}; let group = key => groups[key] || (groups[key] = []); arr.forEach(arr => group(arr[0].key).push(arr)); console.log(groups); console.log(Object.values(groups)); // If you want to get the result you're looking for (not looking at the // order), you can simply flatten all groups of 1 element. Although // depending on your use case I recommend sticking with the above. console.log(Object.values(groups).map(group => group.length === 1 ? group[0] : group));
let arr = [ [ {"key":2}, {"key":2} ], [ {"key":3} ], [ {"key":1}, {"key":1} ], [ {"key":1} ] ] var myMap = new Map(); for (i = 0; i < arr.length; i++) { if(!myMap.has(arr[i][0]['key'])){ myMap.set(arr[i][0]['key'],i) }else if(myMap.get(arr[i][0]['key'])===undefined){ myMap.set(arr[i][0]['key'],i) }else{ myMap.set(arr[i][0]['key'],myMap.get(arr[i][0]['key'])+','+i) } } var out =[]; for(var v of myMap.values()){ var s = String(v).split(","); var fi = s[0] var subarray =[] for(var i in s){ subarray.push(arr[s[i]]) } out[fi] = subarray; } You will find your response in out array. Hope that it works for you
Pourquoi avez-vous choisi cette structure? Quel est le cas d'utilisation derrière cela? Cela ressemble à un problème XY.
2 tableaux où les objets ont la même valeur de clé sont regroupés en tableau: [tableau, tableau]
c'est un jeu de données étrange, je ne peux prévoir aucun avantage d'une telle structure, ni pour les performances, ni pour la lisibilité.
Oui je vois ça. mais pourquoi? Pourquoi pas
[{key: 1, count: 2}, ...]
?J'obtiens une réponse JSON de l'API et je dois la regrouper pour qu'elle s'affiche en blocs. La structure du tableau initial est le résultat d'un regroupement de premier niveau, et la tâche est la deuxième afin de les lister en divs comme j'ai besoin