0
votes

Comment puis-je fusionner de manière fiable des objets de ces 2 tableaux et boucle la matrice résultante, dans Svelte?

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" },
]


0 commentaires

4 Réponses :


1
votes

Une approche pourrait être d'utiliser réduire code> en fusionnant les deux tableaux à l'autre, puis en prenant des objets. Voici un exemple:

p>

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);


3 commentaires

Laquelle des méthodes fonctionnerait même si les 2 matrices où inégale> de longueur?


Quel tableau dans ce cas serait le définissant pour la nouvelle longueur?


@Razvanzamfir les deux fonctionnera. En cas de Réduire , 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.



1
votes

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)


1 commentaires

Et si je veux le résultat pour contenir uniquement le tableau Nom et stand_code propriétés, comment puis-je faire cela?



4
votes

Certaines des réponses ici utilisent essentiellement des boucles imbriquées (A 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.

Une solution beaucoup plus évolutive consiste à utiliser Recherche: P>

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) || {}));
});


4 commentaires

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 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 . 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 à itérer via les touches et à l'intérieur, un carte à itérer via la carte et ils font tous les deux des copies de la Tableau Depuis le Mécanisme interne de CaRAY.Drom utilise aussi? Est-il possible d'éviter le tableau.From et la carte été imbriquée?


@ Sven.hig, la différence est que ... lookups.map (...) Boucle sur 2 recherches, pas n 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 utilise mappe interne; Il n'y a aucune raison pour laquelle cela serait



1
votes

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))


0 commentaires