J'ai 2 tableaux d'objets, avec chaque objet contenant des informations que je souhaite fusionner. Les tableaux ont une clé commune:
let dial = [ { code: "IL", dial_code: "+972" }, { code: "AF", dial_code: "+93" }, { code: "AL", dial_code: "+355" }, ]
4 Réponses :
Une approche pourrait être d'utiliser p> réduire code> en fusionnant les deux tableaux à l'autre, puis en prenant des objets. Voici un exemple:
var dial = [ { code: "IL", dial_code: "+972" }, { code: "AF", dial_code: "+93" }, { code: "AL", dial_code: "+355" },];
var countries = [ { code: "AF", name: "Afghanistan" }, { code: "AL", name: "Albania" },{ code: "IL", name: "Israel" }];
var result= countries.map(country=>({...country, dialo_code:dial.find(p=>p.code==country.code)?.dial_code}));
console.log(result);
Laquelle des méthodes fonctionnerait même si les 2 matrices où
Quel tableau dans ce cas serait le définissant pour la nouvelle longueur?
@Razvanzamfir les deux fonctionnera. En cas de Réduire code>, dites si Dial_Code n'est pas présent, alors il n'entrera pas la touche de l'objet, et si vous utilisez la deuxième clé, la clé sera présente mais avec une valeur non définie. Mieux vaut la tester sur votre avec quelques données factices. et choisissez un.
Voici une approche différente
p>
let countries = [ { code: "AF", name: "Afghanistan" }, { code: "AL", name: "Albania" }, { code: "IL", name: "Israel" }, ] let dial = [ { code: "AF", dial_code: "+93" }, { code: "AL", dial_code: "+355" }, { code: "IL", dial_code: "+972" }, { code: "ILi", dial_code: "+972" } ] result=[] dial.forEach((x)=>{ countries.forEach(o=>{ if(x.code==o.code) return result.push(Object.assign({},o,x)) }) }) console.log(result)
Et si je veux le résultat code> pour contenir uniquement le tableau code> Nom code> et stand_code code> propriétés, comment puis-je faire cela?
Certaines des réponses ici utilisent essentiellement des boucles imbriquées (A Une solution beaucoup plus évolutive consiste à utiliser Recherche: P> foreach code> à l'intérieur d'un
foreach code> ou a
trouver code> à l'intérieur d'une carte
code>). C'est probablement bien dans cette situation, mais la performance de cette approche est O (n ^ 2), qui est un drapeau rouge. Si vous aviez un tableau troisième em> de données que vous vouliez fusionner avec une approche similaire, cela deviendrait O (n ^ 3), etc.
const sources = [countries, dial]; // plus anything you add in future!
const codes = new Set( // using a set is an easy way to dedupe
sources.map(source => source.map(d => d.code)).flat()
);
const lookups = sources.map(source => {
const lookup = new Map();
source.forEach(d => lookup.set(d.code, d));
return lookup;
});
const combined = Array.from(codes, code => {
return Object.assign({}, ...lookups.map(d => d.get(code) || {}));
});
Très belle solution. Cependant, j'ai exécuté un test de performance avec votre solution vs le forach imbéh, et il semble au moins dans cette situation que cette solution est plus lente que la nourriture imbriquée, elle semble également ajouter des données indésirables dans la situation où les tableaux ne sont pas de même longueur, mais peut-être que cela peut être contourné cependant
L'approche peut facilement être modifiée pour utiliser l'ensemble de tous les codes apparaissant dans les sources ou dans. RE Performance: Oui, évidemment lorsque vous avez trois articles, la technique avec le moins de configuration va gagner. Mais ce n'est pas la chose à optimiser. L'approche ici est O (n), alors que l'approche foreach code> est O (n ^ 2) dans le meilleur cas. Les données en question sont une liste de pays, dont il y a environ 200 - avec cette quantité de données, l'algorithme O (n) est déjà plusieurs fois plus rapide que l'approche naïf
foreach code>. Avec (disons) 10 000 articles, O (n ^ 2) est catastrophiquement lent.
Merci pour votre commentaire, je suis d'accord, je suis d'accord que la solution est évolutive et elle est définitivement plus rapide pour les grandes données, mais ne considérez-vous pas la dernière ligne de votre solution une sorte de boucle imbriquée? puisque vous utilisez array.from code> à itérer via les touches et à l'intérieur, un
carte code> à itérer via la carte code> et ils font tous les deux des copies de la Tableau Depuis le Mécanisme interne de CaRAY.Drom utilise code> aussi? Est-il possible d'éviter le tableau.From et la carte été imbriquée?
@ Sven.hig, la différence est que ... lookups.map (...) code> Boucle sur 2 recherches, pas n i> des lignes de données. C'est pourquoi c'est O (n) et non O (n ^ 2). En dehors, je doute beaucoup que
array.from code> utilise
mappe code> interne; Il n'y a aucune raison pour laquelle cela serait
Je pense que le tri est beaucoup plus efficace que de faire une structure de données intégrée.
let countries = [ { code: "AF", name: "Afghanistan" }, { code: "AL", name: "Albania" }, { code: "IL", name: "Israel" }, ] let dial = [ { code: "AF", dial_code: "+93" }, { code: "AL", dial_code: "+355" }, { code: "IL", dial_code: "+972" }, ] const combine = (arr1, arr2) => { const combined = arr1.concat(arr2) combined.sort((x, y) => x.code.localeCompare(y.code)) const result = [combined[0]] for (let i = 1; i < combined.length; i++) { if (combined[i].code == combined[i - 1].code) { result[result.length - 1] = { ...result[result.length - 1], ...combined[i] } } else { result.push(combined[i]) } } return result } console.log(combine(countries, dial))