In javascript, how do you search an array for a substring match

JavascriptArraysSearch

Javascript Problem Overview


I need to search an array in javascript. The search would be for only part of the string to match as the string would have addtional numbers assigned to it. I would then need to return the successfully matched array element with the full string.

i.e.

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

I need to search for the array element with "id-" in it and i need to pull the rest of the text in the element as well (ie. "id-3-text").

Thanks

Javascript Solutions


Solution 1 - Javascript

If you're able to use Underscore.js in your project, the _.filter() array function makes this a snap:

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

The iterator function can do whatever you want as long as it returns true for matches. Works great.

Update 2017-12-03:
This is a pretty outdated answer now. Maybe not the most performant option in a large batch, but it can be written a lot more tersely and use native ES6 Array/String methods like .filter() and .includes() now:

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

Note: There's no <= IE11 support for String.prototype.includes() (Edge works, mind you), but you're fine with a polyfill, or just fall back to indexOf().

Solution 2 - Javascript

People here are making this waaay too difficult. Just do the following...

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

findIndex() is an ES6 higher order method that iterates through the elements of an array and returns the index of the first element that matches some criteria (provided as a function). In this case I used ES6 syntax to declare the higher order function. element is the parameter of the function (which could be any name) and the fat arrow declares what follows as an anonymous function (which does not need to be wrapped in curly braces unless it takes up more than one line).

Within findIndex() I used the very simple includes() method to check if the current element includes the substring that you want.

Solution 3 - Javascript

The simplest way to get the substrings array from the given array is to use filter and includes:

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

The above one will return an array of substrings.

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

The above one will return the first result element from the array.

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

The above one will return the index of the first result element from the array.

Solution 4 - Javascript

In your specific case, you can do it just with a boring old counter:

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

But if your array is sparse, you can do it more efficiently with a properly-designed for..in loop:

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

Beware naive for..in loops that don't have the hasOwnProperty and !isNaN(parseInt(key, 10)) checks; here's why.


Off-topic:

Another way to write

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

is

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

...which is less typing for you, and perhaps (this bit is subjective) a bit more easily read. The two statements have exactly the same result: A new array with those contents.

Solution 5 - Javascript

Just search for the string in plain old indexOf

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

Solution 6 - Javascript

The simplest vanilla javascript code to achieve this is

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

Solution 7 - Javascript

For a fascinating examination of some of the alternatives and their efficiency, see John Resig's recent posts:

(The problem discussed there is slightly different, with the haystack elements being prefixes of the needle and not the other way around, but most solutions are easy to adapt.)

Solution 8 - Javascript

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

Filter array with string match. It is easy and one line code.

Solution 9 - Javascript

ref: https://stackoverflow.com/questions/4556099/in-javascript-how-do-you-search-an-array-for-a-substring-match/5792042#5792042

The solution given here is generic unlike the [solution 4556343#4556343][1], which requires a previous parse to identify a string with which to join(), that is not a component of any of the array strings.
Also, in that code /!id-[^!]*/ is more correctly, /![^!]*id-[^!]*/ to suit the question parameters:

  1. "search an array ..." (of strings or numbers and not functions, arrays, objects, etc.)
  2. "for only part of the string to match " (match can be anywhere)
  3. "return the ... matched ... element" (singular, not ALL, as in "... the ... elementS")
  4. "with the full string" (include the quotes)

... NetScape / FireFox solutions (see below for a JSON solution):

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

or

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

displays "x'!x'\"id-2".
Perhaps raiding the array to find ALL matches is 'cleaner'.

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

displays:

"x'!x'"id-2"

 "' \"id-1 \""

 "id-3-text"

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

displays:

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

,"' \"id-1 \""

,"id-3-text"

wrinkles:

  • The "unescaped" global RegExp is /[^\]"([^"]|\")*id-([^"]|\")*[^\]"/g with the \ to be found literally. In order for ([^"]|\")* to match strings with all "'s escaped as \", the \ itself must be escaped as ([^"]|\\")*. When this is referenced as a string to be concatenated with id-, each \ must again be escaped, hence ([^"]|\\\\")*!
  • A search ID that has a \, *, ", ..., must also be escaped via .toSource() or JSON or ... .
  • null search results should return '' (or "" as in an EMPTY string which contains NO "!) or [] (for all search).
  • If the search results are to be incorporated into the program code for further processing, then eval() is necessary, like eval('['+findInRA(RA,ID).join(',')+']').


Digression:
Raids and escapes? Is this code conflicted?
The semiotics, syntax and semantics of /* it has no ... =! */ emphatically elucidates the escaping of quoted literals conflict.

Does "no =" mean:

  • "no '=' sign" as in javascript:alert('\x3D') (Not! Run it and see that there is!),
  • "no javascript statement with the assignment operator",
  • "no equal" as in "nothing identical in any other code" (previous code solutions demonstrate there are functional equivalents),
  • ...

Quoting on another level can also be done with the immediate mode javascript protocol URI's below. (// commentaries end on a new line (aka nl, ctrl-J, LineFeed, ASCII decimal 10, octal 12, hex A) which requires quoting since inserting a nl, by pressing the Return key, invokes the URI.)

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

Note: Cut and paste any of the javascript: lines as an immediate mode URI (at least, at most?, in FireFox) to use first javascript: as a URI scheme or protocol and the rest as JS labels.

[1]: https://stackoverflow.com/questions/4556099/in-javascript-how-do-you-search-an-array-for-a-substring-match/4556343#4556343 "not generic"

Solution 10 - Javascript

I've created a simple to use library (ss-search) which is designed to handle objects, but could also work in your case:

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

The advantage of using this search function is that it will normalize the text before executing the search to return more accurate results.

Solution 11 - Javascript

Another possibility is

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

that IMO may make sense if you can have a special char delimiter (here i used "!"), the array is constant or mostly constant (so the join can be computed once or rarely) and the full string isn't much longer than the prefix searched for.

Solution 12 - Javascript

>Here's your expected snippet which gives you the array of all the matched values -

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

Solution 13 - Javascript

I think this may help you. I had a similar issue. If your array looks like this:

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

You can do a simple "for" loop to return the instance in the array when you get a match.

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

We create an empty variable, c to host our answer. We then loop through the array to find where the array object (e.g. "page1") matches our indexOf("page"). In this case, it's 0 (the first result)

Happy to expand if you need further support.

Solution 14 - Javascript

this worked for me .

    const filterData = this.state.data2.filter(item=>((item.name.includes(text)) || (item.surname.includes(text)) || (item.email.includes(text)) || (item.userId === Number(text))) ) ;

Solution 15 - Javascript

Use this function for search substring Item.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionreub77View Question on Stackoverflow
Solution 1 - JavascriptnickbView Answer on Stackoverflow
Solution 2 - Javascriptuser10302261View Answer on Stackoverflow
Solution 3 - Javascriptsmnth90View Answer on Stackoverflow
Solution 4 - JavascriptT.J. CrowderView Answer on Stackoverflow
Solution 5 - JavascriptJohnnyJSView Answer on Stackoverflow
Solution 6 - JavascriptKarthikView Answer on Stackoverflow
Solution 7 - JavascriptTgrView Answer on Stackoverflow
Solution 8 - JavascriptBiswajitView Answer on Stackoverflow
Solution 9 - JavascriptEkimView Answer on Stackoverflow
Solution 10 - JavascriptYann ThibodeauView Answer on Stackoverflow
Solution 11 - Javascript6502View Answer on Stackoverflow
Solution 12 - JavascriptTushar WalzadeView Answer on Stackoverflow
Solution 13 - JavascriptAndrew SainsburyView Answer on Stackoverflow
Solution 14 - JavascriptNurdoğan AkdağView Answer on Stackoverflow
Solution 15 - JavascriptVivekanand PandaView Answer on Stackoverflow