Reputation: 1289
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 additional components. I would then need to return the successfully matched array element with the full string.
Example:
const windowArray = [ "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 (i.e. "id-3-text"
).
How do I do that?
Upvotes: 113
Views: 235696
Reputation: 3819
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);
Upvotes: 0
Reputation: 828
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.
Upvotes: 61
Reputation: 1261
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.
Upvotes: 1
Reputation: 1472
Just search for the string in plain old indexOf
arr.forEach(function(a){
if (typeof(a) == 'string' && a.indexOf('curl')>-1) {
console.log(a);
}
});
Upvotes: 14
Reputation: 877
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-"))
Upvotes: 0
Reputation: 9
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))) ) ;
Upvotes: -1
Reputation: 125
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.
Upvotes: 0
Reputation: 1037
let url = item.product_image_urls.filter(arr=>arr.match("homepage")!==null)
Filter array with string match. It is easy and one line code.
Upvotes: 2
Reputation:
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.
Upvotes: 106
Reputation: 2930
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()
.
Upvotes: 93
Reputation: 1091
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"]
Upvotes: 5
Reputation: 959
ref: In javascript, how do you search an array for a substring match
The solution given here is generic unlike the solution 4556343#4556343, 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:
... 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:
/[^\]"([^"]|\")*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 ([^"]|\\\\")*
!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).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:
javascript:alert('\x3D')
(Not! Run it and see that there is!),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.
Upvotes: 1
Reputation: 114599
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.
Upvotes: 0
Reputation: 1075755
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.
Upvotes: 21