3
votes

Rechercher dans un tableau Javascript multidimensionnel

J'ai un tableau configuré comme suit:

var array = [["A1", "left:81px"], ["A2", "left:145px"],...]

Le but de ceci est de prendre une entrée utilisateur et de rechercher dans ce tableau pour trouver l'emplacement vers lequel déplacer un élément. Si l'entrée de l'utilisateur est "A1" , comment puis-je analyser ce tableau pour définir une variable égale à "left:81px"?


4 commentaires

Bienvenue dans stackoverflow. Qu'avez-vous essayé? Ce n'est pas un service d'écriture de code et nous attendons des gens qu'ils montrent qu'ils ont fait des efforts pour essayer de résoudre le problème eux-mêmes. Veuillez lire le centre d'aide et le Comment demander en particulier


Pouvez-vous élargir votre réponse? Je ne connais pas très bien JavaScript et je ne comprends pas très bien.


@messerbill alors vous devriez savoir que map est une mauvaise recommandation pour ce problème ...


@messerbill map effectue une opération sur chaque élément du tableau d'entrée et produit un nouveau tableau de sortie. cela n'a rien à voir avec la question posée - nous ne voulons pas effectuer d'opération sur chaque élément et nous ne voulons pas créer un nouveau tableau.


3 Réponses :


4
votes

Utilisez find et une simple déstructuration.

var array = [
  ["A1", "left:81px"],
  ["A2", "left:145px"]
];

const input = "A1";
let res = "";

for (let i = 0; i < array.length; i++) {
  if (array[i][0] == input) {
    res = array[i][1];
    break;
  }
}

console.log(res);

Ce qui précède renvoie undefined si aucune valeur n'est trouvée.

Code un peu plus simple:

var array = [
  ["A1", "left:81px"],
  ["A2", "left:145px"]
];

const [, res] = array.find(([k]) => k == "A1") || [];

console.log(res);


17 commentaires

dans votre premier exemple, utilisez array.find (...) || [] de cette façon [ res] = ... ne générera jamais d'erreur. Si aucune correspondance n'est trouvée, res sera indéfini


OK @ user633183, je modifierai ma réponse pour améliorer la stabilité.


Correction de @ user633183, mieux maintenant? (Je n'ai pas besoin d'ajouter au filtre car c'est [] par défaut).


Non, filter est pire car il continuera à traverser le tableau même après que la première correspondance soit trouvée. La question cherche uniquement à récupérer une valeur unique .


D'accord, corrigé maintenant @ user633183 - mieux?


array.find (...) || "Valeur par défaut" ne fonctionne pas non plus car [ res] ... déstructurera la chaîne, ce qui entraînera la création attribué à res ^ _ ^


Vous venez de réécrire ma conception pour la deuxième solution) gentil homme


Oups, désolé - devrais-je simplement le mettre dans un tableau || [ "Valeur par défaut"] ?


Que voulez-vous dire @AksenP?


@JackBashford ... || [ "Default Value"] fonctionne mais c'est plutôt moche. Si vous vouliez ajouter une fonctionnalité de valeur par défaut, je ferais plus tôt: const r = array.find (...); retourne r === indéfini? "valeur par défaut": r [1]; ce n'est pas aussi joli, mais c'est plus clair, imo. Ma suggestion originale d'ajouter ... || [] donne res = undefined qui correspond au comportement de find et est probablement assez bon.


Cool, je vais juste ajouter cela alors - seriez-vous satisfait dans ce cas?


Correction de @ user633183.


@JackBashford a l'air mieux, mais vous avez déjà eu mon vote favorable même dans votre première révision '^ _ ^


Mon mauvais @ user633183 - toute infraction potentielle retirée. Désolé pour l'hypothèse - je viens de faire arriver souvent cela où le premier commentateur «d'amélioration» est le downvoter.


@JackBashford J'avais ce soupçon - c'est toujours gênant d'offrir un commentaire sur une réponse avec un vote négatif qui n'est pas le vôtre. Je vous ai vu sur le site et vous faites du bon travail ici. Continuez comme ça et ne laissez pas les mordeurs de cheville vous abattre: D


Merci beaucoup pour les commentaires positifs @ user633183 - en tant que l'un des utilisateurs les plus expérimentés du site, à la fois en JavaScript et plus généralement, je prends cela à une valeur nominale très élevée.


Dans votre deuxième exemple, lorsque je fais «i



1
votes

En supposant que les tableaux internes sont toujours structurés comme [clé, valeur] :

const data = {
  A1: 'left:81px',
  A2: 'left:145px'
};

const query = 'A1';

const result = data[query];
console.log(result);

Si possible, vous devriez utiliser une meilleure structure de données (semblable à une carte) pour cela:

// this is your array.
const array = [["A1", "left:81px"], ["A2", "left:145px"]]

// user input:
const query = "A1";

// find an inner array in array whose first element matches the user input
const [, result] = array.find(([key]) => key === query) || []

console.log(result);

La version tableau a un runtime linéaire où le second est le temps constant. Si vous faites souvent cette recherche, il vaut la peine de convertir votre représentation de tableau en un objet


0 commentaires

0
votes

Pour obtenir le résultat attendu, utilisez Object.fromEntries pour convertir un tableau de paires clé / valeur en objet - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries

  1. Convertit le tableau de paires clé-valeur en objet à l'aide d'Object.fromEntries.
  2. Rechercher une valeur à l'aide d'une valeur clé telle que A1, A2

exemple de code de travail

var arr = [["A1", "left:81px"], ["A2", "left:145px"]]
var obj = arr.reduce((acc,v)=>{
    acc[v[0]] = v[1]
    return acc
  }, {})
console.log(obj['A1'])

Option 2: Utilisation de la clé de réduction et de conversion, paire de valeurs tableau en objet une fois et utilisation pour des recherches supplémentaires à chaque fois et également pour une meilleure compatibilité du navigateur par rapport à Object.fromEntries >

var arr = [["A1", "left:81px"], ["A2", "left:145px"]]
function findVal(word, arr){
  var obj = Object.fromEntries(arr)
  return obj[word]
  
}
console.log(findVal('A1', arr))


7 commentaires

L'inconvénient majeur de cette réponse est que toute l'entrée doit être transformée avant que la réponse puisse être renvoyée - c'est un gaspillage comparé aux approches qui arrêtent de lire l'entrée dès que la correspondance est rencontrée.


@ user633183, une approche consiste à le convertir en objet une fois pour faciliter les recherches ultérieures, au lieu de le boucler pour chaque recherche


Correct, si de nombreuses recherches sont nécessaires, un type de données offrant de meilleures capacités de recherche offrirait de bien meilleures performances. Pensez à Map dans ce cas.


@ user633183, option 2 mise à jour pour créer un objet à partir de ce tableau et l'utiliser pour toutes les autres recherches suivantes


Votre deuxième solution réduire souffre du même problème. Il traversera tout le tableau d'entrée même si un résultat pourrait être renvoyé plus tôt. Utiliser réduire comme ceci revient à écrire à la main Object.fromEntries .


oui @ user633183, je suis sûr que la recherche se produira plusieurs fois pour ce tableau, elle souffre la première fois et facilite les recherches suivantes avec une meilleure complexité temporelle dès la deuxième fois plutôt que de boucler à chaque fois


Je suis d'accord qu'une structure de données plus appropriée permettrait de bien meilleures réponses à cette question