Wie durchsuchen Sie in Javascript ein Array nach einer Teilstring-Übereinstimmung?

75

Ich muss ein Array in Javascript suchen. Bei der Suche würde nur ein Teil der Zeichenfolge übereinstimmen, da der Zeichenfolge zusätzliche Nummern zugewiesen würden. Ich müsste dann das erfolgreich übereinstimmende Array-Element mit der vollständigen Zeichenfolge zurückgeben.

dh

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

Ich muss nach dem Array-Element suchen, "id-"in dem es sich befindet, und ich muss auch den Rest des Textes in das Element ziehen (dh "id-3-text").

Vielen Dank

reub77
quelle
17
Sie können das Array einfach filtern results = arr.filter(function (v) {return /id-/.test(v)});. Und dann können Sie mit den Ergebnissen machen, was Sie wollen.
zzzzBov
@zzzzBov Ihr Kommentar ist eine Antwort wert ...
Skippy le Grand Gourou

Antworten:

18

In Ihrem speziellen Fall können Sie dies nur mit einem langweiligen alten Zähler tun:

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

Wenn Ihr Array jedoch spärlich ist , können Sie dies mit einer ordnungsgemäß gestalteten for..inSchleife effizienter tun :

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

Passen Sie auf naive for..inSchleifen auf, die das nicht haben hasOwnPropertyund !isNaN(parseInt(key, 10))prüfen; Hier ist warum .


Off-Topic :

Eine andere Art zu schreiben

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

ist

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

... was für Sie weniger tippt und vielleicht (dieses Bit ist subjektiv) etwas leichter zu lesen ist. Die beiden Anweisungen haben genau das gleiche Ergebnis: Ein neues Array mit diesen Inhalten.

TJ Crowder
quelle
62

Wenn Sie Underscore.js in Ihrem Projekt verwenden können, macht die Array-Funktion _.filter () dies zu einem Kinderspiel :

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

Die Iteratorfunktion kann tun, was Sie wollen, solange sie für Übereinstimmungen true zurückgibt. Funktioniert super.

Update 2017-12-03:
Dies ist jetzt eine ziemlich veraltete Antwort. Vielleicht nicht die leistungsstärkste Option in einem großen Stapel, aber sie kann viel knapper geschrieben werden und native ES6-Array / String-Methoden wie .filter()und .includes()jetzt verwenden:

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

Hinweis: Es gibt keine <= IE11-Unterstützung für String.prototype.includes()(Edge funktioniert, wohlgemerkt ), aber Sie können mit einer Polyfüllung gut umgehen oder einfach darauf zurückgreifen indexOf().

Nickb
quelle
@ Floppy88 Nun, die ursprüngliche Frage war für die Suche in einem einfachen Array; Es ist jetzt auch etwas lang (kein Unterstrich erforderlich). Würden Sie nach Objektwerten oder Schlüsseln suchen? Ein Beispiel für einen Anwendungsfall wäre hilfreich.
Nickb
Ich muss in Objektschlüssel suchen
Floppy88
1
@ Floppy88 Nur verwenden Object.keys(yourArrayName), was ein Array zurückgibt. Sie können die gleiche Technik wie oben anwenden .filter().
Nickb
Die Verwendung der Funktion .filter () ist in den meisten Fällen die beste Methode
Anand Raja
54

Die Leute hier machen das zu schwierig. Mach einfach folgendes ...

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

findIndex () ist eine ES6-Methode höherer Ordnung, die die Elemente eines Arrays durchläuft und den Index des ersten Elements zurückgibt, das einigen Kriterien entspricht (als Funktion bereitgestellt). In diesem Fall habe ich die ES6-Syntax verwendet, um die Funktion höherer Ordnung zu deklarieren. elementist der Parameter der Funktion (der ein beliebiger Name sein kann) und der Fettpfeil deklariert das Folgende als anonyme Funktion (die nicht in geschweifte Klammern gesetzt werden muss, es sei denn, sie nimmt mehr als eine Zeile ein).

Innerhalb habe findIndex()ich die sehr einfache includes()Methode verwendet, um zu überprüfen, ob das aktuelle Element den gewünschten Teilstring enthält.


quelle
Erstaunliche Antwort, genau das, wonach ich gesucht habe. Vielen Dank!
Rami
18

Der einfachste Weg, um das Teilstrings-Array aus dem angegebenen Array abzurufen, ist die Verwendung von filter und enthält:

myArray.filter(element => element.includes("substring"));

Das obige gibt das Teilzeichenfolgen-Array zurück.

myArray.find(element => element.includes("substring"));

Das obige gibt das erste Ergebniselement aus dem Array zurück.

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

Das obige gibt den Index des ersten Ergebniselements aus dem Array zurück.

smnth90
quelle
Dies gibt das erste Spiel zurück
00-BBB
1
@ 00-BBB Fund durch Filter ersetzen
Hos Mercury
Danke @Hos Mercury. Ja, Filter gibt die Liste zurück
smnth90
12

Suchen Sie einfach nach der Zeichenfolge in einfach alt indexOf

arr.forEach(function(a){
    if (typeof(a) == 'string' && a.indexOf('curl')>-1) {
            console.log(a);
    }        
});
JohnnyJS
quelle
Sie gilt nicht für Nullwerte.
Tushar Walzade
Wenn Sie gemischte Typen in Ihrem Array haben, ist das nur eine schlechte Praxis, aber ich habe die Prüfung trotzdem hinzugefügt.
JohnnyJS
4

Der einfachste Vanille-Javascript-Code, um dies zu erreichen, ist

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"]
Karthik
quelle
1

ref: Wie durchsucht man in Javascript ein Array nach einer Teilstring-Übereinstimmung?

Die hier angegebene Lösung ist generisch im Gegensatz zur Lösung 4556343 # 4556343 , für die eine vorherige Analyse erforderlich ist, um eine Zeichenfolge zu identifizieren, mit der zu arbeiten ist join(), die keine Komponente einer der Array-Zeichenfolgen ist.
Außerdem ist dieser Code /!id-[^!]*/korrekter, /![^!]*id-[^!]*/um den Fragenparametern zu entsprechen:

  1. "Suche ein Array ..." (von Zeichenfolgen oder Zahlen und nicht von Funktionen, Arrays, Objekten usw.)
  2. "Damit nur ein Teil der Zeichenfolge übereinstimmt" (Übereinstimmung kann überall sein)
  3. "Rückgabe des ... übereinstimmenden ... Elements" (Singular, nicht ALL, wie in "... the ... elementS")
  4. "mit der vollen Zeichenfolge" (einschließlich Anführungszeichen)

... NetScape / FireFox-Lösungen (siehe unten für a JSON Lösung):

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

oder

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

Anzeigen "x'!x'\"id-2".
Vielleicht ist es "sauberer", das Array zu durchsuchen, um ALLE Übereinstimmungen zu finden.

/* 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') ) ;

zeigt an:

     "x '! x'" id-2 "

     "'" id-1 ""

     "id-3-text"

Verwenden von 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') ) ;

zeigt an:

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

    , "'" id-1 ""

    , "id-3-text"

Falten:

  • Das "unescaped" globale RegExp ist /[^\]"([^"]|\")*id-([^"]|\")*[^\]"/gmit dem \buchstäblich zu finden. Um ([^"]|\")*Zeichenfolgen mit allen "als maskierten Zeichenfolgen abzugleichen \", \muss die selbst als maskiert werden ([^"]|\\")*. Wenn dies als zu verkettende Zeichenfolge bezeichnet wird id-, \muss jede erneut maskiert werden([^"]|\\\\")* !
  • Eine Suche , IDdie hat eine \, *, ", ..., muss auch über entwertet werden .toSource()oder JSONoder ....
  • nullSuchergebnisse sollten zurückgeben ''(oder ""wie in einer LEEREN Zeichenfolge, die NO enthält "!) oder [](für alle Suchvorgänge).
  • Wenn die Suchergebnisse zur weiteren Verarbeitung in den Programmcode aufgenommen werden sollen, eval()ist z eval('['+findInRA(RA,ID).join(',')+']').

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

Exkurs:
Überfälle und Fluchten? Ist dieser Code in Konflikt geraten?
Die Semiotik, Syntax und Semantik des /* it has no ... =! */nachdrücklichen Konflikts wird deutlich.

Bedeutet "nein =":

  • "no '=' sign" wie in javascript:alert('\x3D') (Not! Führen Sie es aus und sehen Sie, dass es gibt!),
  • "keine Javascript-Anweisung mit dem Zuweisungsoperator",
  • "nicht gleich" wie in "nichts identisch in einem anderen Code" (frühere Codelösungen zeigen, dass es funktionale Äquivalente gibt),
  • ...

Das Zitieren auf einer anderen Ebene kann auch mit den unten aufgeführten Javascript-Protokoll-URIs im Sofortmodus erfolgen. (// Kommentare enden in einer neuen Zeile (auch bekannt als nl, Strg-J, LineFeed, ASCII-Dezimalzahl 10, Oktal 12, Hex A). Dies erfordert ein Anführungszeichen, da durch Einfügen eines nl durch Drücken der Eingabetaste der URI aufgerufen wird.)

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

Hinweis: Schneiden Sie eine der javascript:Zeilen aus und fügen Sie sie als URI im Sofortmodus ein (zumindest höchstens? In FireFox), um sie zuerst javascript:als URI-Schema oder -Protokoll und den Rest als JS-Beschriftung zu verwenden.

Ekim
quelle
1
let url = item.product_image_urls.filter(arr=>arr.match("homepage")!==null)

Filterarray mit String-Übereinstimmung. Es ist einfach und ein Zeilencode.

Biswajit
quelle
1

das hat bei mir funktioniert.

    const filterData = this.state.data2.filter(item=>((item.name.includes(text)) || (item.surname.includes(text)) || (item.email.includes(text)) || (item.userId === Number(text))) ) ;
Nurdoğan Akdağ
quelle
1

Ich habe eine einfach zu verwendende Bibliothek ( ss-search ) erstellt, die für die Verarbeitung von Objekten ausgelegt ist, aber auch in Ihrem Fall funktionieren könnte:

search(windowArray.map(x => ({ key: x }), ["key"], "SEARCH_TEXT").map(x => x.key)

Der Vorteil dieser Suchfunktion besteht darin, dass der Text vor dem Ausführen der Suche normalisiert wird, um genauere Ergebnisse zu erhalten.

Yann Thibodeau
quelle
0

Eine andere Möglichkeit ist

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

Diese IMO kann sinnvoll sein, wenn Sie einen speziellen Zeichenbegrenzer haben können (hier habe ich "!" verwendet), das Array konstant oder größtenteils konstant ist (so dass der Join einmal oder selten berechnet werden kann) und die vollständige Zeichenfolge nicht viel länger ist als das gesuchte Präfix.

6502
quelle
0

Hier ist Ihr erwarteter Ausschnitt, der Ihnen das Array aller übereinstimmenden Werte gibt -

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

Tushar Walzade
quelle
0

Ich denke, das kann dir helfen. Ich hatte ein ähnliches Problem. Wenn Ihr Array so aussieht:

var array = ["page1","1973","Jimmy"]; 

Sie können eine einfache "for" -Schleife ausführen, um die Instanz im Array zurückzugeben, wenn Sie eine Übereinstimmung erhalten.

var c; 
for (i = 0; i < array.length; i++) {
if (array[i].indexOf("page") > -1){ 
c = i;}
} 

Wir erstellen eine leere Variable, c, um unsere Antwort zu hosten. Wir durchlaufen dann das Array, um herauszufinden, wo das Array-Objekt (z. B. "page1") mit unserem indexOf ("page") übereinstimmt. In diesem Fall ist es 0 (das erste Ergebnis)

Gerne erweitern, wenn Sie weitere Unterstützung benötigen.

Andrew Sainsbury
quelle
2
Obwohl dieses Code-Snippet möglicherweise die Frage beantwortet, einschließlich einer Erklärung, warum und wie es zur Lösung des Problems beiträgt, verbessert es die Qualität und Langlebigkeit Ihrer Antwort, insbesondere bei älteren Fragen wie dieser. Siehe "Wie schreibe ich eine gute Antwort?" .
träge
Hi Slothiful - danke für das Feedback. Ich habe meine Antwort entsprechend aktualisiert
Andrew Sainsbury
0

Verwenden Sie diese Funktion für die Suche nach Teilzeichenfolgen.

function checkItem(arrayItem, searchItem) {
  return arrayItem.findIndex(element => element.includes(searchItem)) >= 0
}

function getItem(arrayItem, getItem) {
  return arrayItem.filter(element => element.includes(getItem))
}

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


console.log(checkItem(arrayItem, "id-"))
console.log(checkItem(arrayItem, "vivek"))
console.log(getItem(arrayItem, "id-"))

Vivekanand Panda
quelle