web-dev-qa-db-fra.com

En javascript, comment rechercher dans un tableau une correspondance de sous-chaîne

J'ai besoin de rechercher un tableau en javascript. La recherche ne doit correspondre qu’à une partie de la chaîne, car des numéros supplémentaires lui sont attribués. J'aurais alors besoin de renvoyer l'élément de tableau correspondant avec succès avec la chaîne complète.

c'est à dire.

var windowArray = new Array ("item","thing","id-3-text","class");

J'ai besoin de rechercher l'élément de tableau avec "id-" dedans et je dois aussi extraire le reste du texte de l'élément (c.-à-d. "id-3-text").

Merci

39
reub77

Dans votre cas spécifique, vous pouvez le faire simplement avec un vieux compteur ennuyeux:

var index, value, result;
for (index = 0; index < windowArray.length; ++index) {
    value = windowArray[index];
    if (value.substring(0, 3) === "id-") {
        // You've found it, the full text is in `value`.
        // So you might grab it and break the loop, although
        // really what you do having found it depends on
        // what you need.
        result = value;
        break;
    }
}

// Use `result` here, it will be `undefined` if not found

Mais si votre tableau est fragmenté , vous pouvez le faire plus efficacement avec une boucle for..in correctement conçue:

var key, value, result;
for (key in windowArray) {
    if (windowArray.hasOwnProperty(key) && !isNaN(parseInt(key, 10))) {
        value = windowArray[key];
        if (value.substring(0, 3) === "id-") {
            // You've found it, the full text is in `value`.
            // So you might grab it and break the loop, although
            // really what you do having found it depends on
            // what you need.
            result = value;
            break;
        }
    }
}

// Use `result` here, it will be `undefined` if not found

Méfiez-vous des boucles naïves for..in qui ne possèdent pas les contrôles hasOwnProperty et !isNaN(parseInt(key, 10)); Voici pourquoi .


Hors sujet:

Une autre façon d'écrire

var windowArray = new Array ("item","thing","id-3-text","class");

est

var windowArray = ["item","thing","id-3-text","class"];

... qui est moins typé pour vous, et peut-être (ce bit est subjectif) un peu plus facile à lire. Les deux instructions ont exactement le même résultat: un nouveau tableau avec ce contenu.

12
T.J. Crowder

Si vous êtes en mesure d'utiliser Underscore.js dans votre projet, la fonction de tableau _.filter () en fait un instantané:

// find all strings in array containing 'thi'
var matches = _.filter(
    [ 'item 1', 'thing', 'id-3-text', 'class' ],
    function( s ) { return s.indexOf( 'thi' ) !== -1; }
);

La fonction itérateur peut faire ce que vous voulez tant qu'elle renvoie true pour les correspondances. Fonctionne très bien.

Mise à jour 2017-12-03:
Ceci est une réponse assez dépassée maintenant. Ce n’est peut-être pas l’option la plus performante dans un grand lot, mais on peut écrire un lot de manière plus nuancée et utiliser maintenant des méthodes ES6 Array/String natives comme .filter() et .includes():

// find all strings in array containing 'thi'
const items = ['item 1', 'thing', 'id-3-text', 'class'];
const matches = items.filter(s => s.includes('thi'));

Remarque: Il n'y a pas de support <= IE11 pour String.prototype.includes() (Edge fonctionne, remarquez-vous), mais vous pouvez utiliser un remplissage multiple, ou simplement revenir à indexOf().

32
nickb

Il suffit de rechercher la chaîne dans le vieux indexOf

arr.forEach(function(a){if (typeof(a) == 'string' && a.indexOf('curl')>-1) console.log(a);})
11
JonnieJS

Les gens ici rendent cela trop difficile. Faites juste ce qui suit ...

myArray.findIndex(element => element.includes("substring"))

findIndex () est une méthode ES6 d'ordre supérieur qui parcourt les éléments d'un tableau et renvoie l'index du premier élément correspondant à certains critères (fourni en tant que fonction). Dans ce cas, j'ai utilisé la syntaxe ES6 pour déclarer la fonction d'ordre supérieur. element est le paramètre de la fonction (qui peut être n'importe quel nom) et la grosse flèche déclare ce qui suit sous la forme d'une fonction anonyme (qui n'a pas besoin d'être entourée d'accolades sauf si elle prend plus d'une ligne). 

Dans findIndex(), j’ai utilisé la méthode très simple includes() pour vérifier si l’élément actuel contient la sous-chaîne souhaitée.

4
user10302261

Le code javascript le plus simple pour y parvenir est: 

var windowArray = ["item", "thing", "id-3-text", "class", "3-id-text"];
var textToFind = "id-";

//if you only want to match id- as prefix 
var matches = windowArray.filter(function(windowValue){
  if(windowValue) {
      return (windowValue.substring(0, textToFind.length) === textToFind);
  }
}); //["id-3-text"]

//if you want to match id- string exists at any position
var matches = windowArray.filter(function(windowValue){
  if(windowValue) {
      return windowValue.indexOf(textToFind) >= 0;
  }
}); //["id-3-text", "3-id-text"]
2
Karthik

ref: En javascript, comment recherchez-vous dans un tableau une correspondance de sous-chaîne

La solution donnée ici est générique contrairement à solution 4556343 # 4556343 , qui nécessite une analyse précédente pour identifier une chaîne avec laquelle join(), qui n'est un composant d'aucune des chaînes du tableau.
En outre, dans ce code /!id-[^!]*/ est plus correctement, /![^!]*id-[^!]*/ pour répondre aux paramètres de la question:

  1. "rechercher un tableau ..." (de chaînes ou de nombres et non de fonctions, de tableaux, d'objets, etc.)
  2. "pour qu'une partie de la chaîne ne corresponde" (la correspondance peut être n'importe où)
  3. "renvoie l'élément ... correspondant ..." (singulier, pas TOUT, comme dans "... les ... éléments")
  4. "avec la chaîne complète" (inclure les guillemets)

... Solutions NetScape/FireFox (voir ci-dessous pour une solution JSON):

javascript:         /* "one-liner" statement solution */
   alert(
      ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] .
         toSource() . match( new RegExp( 
            '[^\\\\]("([^"]|\\\\")*' + 'id-' + '([^"]|\\\\")*[^\\\\]")' ) ) [1]
   );

ou

javascript:
   ID = 'id-' ;
   QS = '([^"]|\\\\")*' ;           /* only strings with escaped double quotes */
   RE = '[^\\\\]("' +QS+ ID +QS+ '[^\\\\]")' ;/* escaper of escaper of escaper */
   RE = new RegExp( RE ) ;
   RA = ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] ;
   alert(RA.toSource().match(RE)[1]) ;

affiche "x'!x'\"id-2".
Peut-être que piller dans le tableau pour trouver TOUTES les correspondances est plus propre.

/* literally (? backslash star escape quotes it!) not true, it has this one v  */
javascript:                            /* purely functional - it has no ... =! */
   RA = ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] ;
   function findInRA(ra,id){
      ra.unshift(void 0) ;                                     /* cheat the [" */
      return ra . toSource() . match( new RegExp(
             '[^\\\\]"' + '([^"]|\\\\")*' + id + '([^"]|\\\\")*' + '[^\\\\]"' ,
             'g' ) ) ;
   }
   alert( findInRA( RA, 'id-' ) . join('\n\n') ) ;

affiche:

 "x '! x' \" id-2 "

" '\ "id-1 \" "

" id-3-text "

Utiliser, JSON.stringify():

javascript:                             /* needs prefix cleaning */
   RA = ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] ;
   function findInRA(ra,id){
      return JSON.stringify( ra ) . match( new RegExp(
             '[^\\\\]"([^"]|\\\\")*' + id + '([^"]|\\\\")*[^\\\\]"' ,
             'g' ) ) ;
   }
   alert( findInRA( RA, 'id-' ) . join('\n\n') ) ;

affiche:

 ["x '! x' \" id-2 "

, '' \" id-1\"" 

, "id-3-text" 

les rides:

  • Le RegExp global "non échappé" est /[^\]"([^"]|\")*id-([^"]|\")*[^\]"/g avec le \ à trouver littéralement. Pour que ([^"]|\")* puisse faire correspondre les chaînes avec tous les " échappés en tant que \", le \ lui-même doit être échappé en tant que ([^"]|\\")*. Lorsque ceci est référencé en tant que chaîne à concaténer avec id-, chaque \ doit à nouveau être échappé, d'où ([^"]|\\\\")*!
  • Une recherche ID qui a un \, *, ", ..., doit également être échappée via .toSource() ou JSON ou ....
  • Les résultats de la recherche null doivent renvoyer '' (ou "" comme dans une chaîne EMPTY contenant NO "!) ou [] (pour toutes les recherches).
  • Si les résultats de la recherche doivent être incorporés au code du programme pour un traitement ultérieur, alors eval() est nécessaire, comme eval('['+findInRA(RA,ID).join(',')+']').

-------------------------------------------------- ------------------------------

Digression:
Raids et évasions? Ce code est-il en conflit?
La sémiotique, la syntaxe et la sémantique de /* it has no ... =! */ élucident catégoriquement l'échappement des conflits entre littéraux cités.

Est-ce que "no =" signifie:

  • "no '=' sign" comme dans javascript:alert('\x3D') (Non! Lancez-le et voyez ce qu'il en est!),
  • "pas de déclaration javascript avec l'opérateur d'affectation",
  • "no égal" comme dans "rien de identique dans aucun autre code" (les solutions de code précédentes démontrent qu'il existe des équivalents fonctionnels),
  • ...

Citer sur un autre niveau peut également être fait avec l'URI du protocole JavaScript en mode immédiat ci-dessous. (// les commentaires se terminent sur une nouvelle ligne (alias nl, ctrl-J, LineFeed, ASCII, décimal 10, octal 12, hex A), qui nécessite une citation depuis l'insertion d'un nl. .)

javascript:/* a comment */  alert('visible')                                ;
javascript:// a comment ;   alert(  'not'  ) this is all comment             %0A;
javascript:// a comment %0A alert('visible but  %\0A  is wrong ')   // X     %0A
javascript:// a comment %0A alert('visible but %'+'0A is a pain to type')   ;

Remarque: Coupez et collez l'une des lignes javascript: en tant qu'URI de mode immédiat (au moins, au plus? Dans FireFox) pour utiliser le premier javascript: en tant que schéma ou protocole d'URI et le reste en tant qu'étiquettes JS.

1
Ekim

Pour un examen fascinant de certaines solutions de rechange et de leur efficacité, voir les récents messages de John Resig:

(Le problème abordé ici est légèrement différent, les éléments de la botte de foin étant les préfixes de l'aiguille et non l'inverse, mais la plupart des solutions sont faciles à adapter.)

1
Tgr

Une autre possibilité est

var res = /!id-[^!]*/.exec("!"+windowArray.join("!"));
return res && res[0].substr(1);

que l’OMI peut avoir un sens si vous pouvez avoir un délimiteur de caractères spécial (ici j’ai utilisé "!"), le tableau est constant ou plutôt constant (la jointure peut donc être calculée une fois ou rarement) et la chaîne complète ne dépasse le préfixe recherché.

0
6502

Voici votre extrait attendu qui vous donne le tableau de toutes les valeurs correspondantes -

var windowArray = new Array ("item","thing","id-3-text","class");

var result = [];
windowArray.forEach(val => {
  if(val && val.includes('id-')) {
    result.Push(val);
  }
});

console.log(result);

0
Tushar Walzade