2

I just started learning javascript and I'm working on small chrome extension that checks a certain website's item listings for any items that contain keywords provided by the user. I'm looking for some help on a method to compare a string to an array of strings.

So I have these variables:

var itemDetails = '[alter] saber 1/8 figure unopened';
var trackingList = ['alter figure', 'magic', 'sword art']; 

I need to check if itemDetails contains any of the strings in trackingList. I know I can use indexOf() like this:

function checkArray(str, arr){
 for(var i=0; i < arr.length; i++){
 if(str.indexOf(arr[i]) > -1)
 return true;
 }
 return false;
}
checkArray(itemDetails,trackingList); // returns false

However, for strings with multiple words in them, such as 'alter figure', I want checkArray() to return true as long as both of the words in the string appear anywhere in itemDetails. So checkArray() should return true in the example above since both 'alter' and 'figure' are in itemDetails.

The method I'm currently using is to split each element in trackingList:

function splitTrackList(arr){
 var newarr = [];
 for(var i = 0; i < arr.length; i++){
 newarr[i] = arr[i].split(" ");
 }
 return newarr;
}
trackList = splitTrackList(trackList); 
// [['alter', 'figure'], ['magic'], ['sword', 'art']]

And then compare using indexOf():

function newCheckArray(str, arr){
 var passed = true;
 for(var i=0; i < arr.length; i++){
 for(var j=0; j < arr[i].length; j++){
 if(str.indexOf(arr[i][j]) == -1){
 passed = false;
 break;
 }
 else passed = true;
 }
 if(passed) //stop loop if match found
 break;
 }
 return passed;
}
newCheckArray(itemDetails,trackingList); //returns true

My method works so far but I'm guessing there is a much faster/efficient way of doing this. Please let me know what you think. Thank you in advance.

asked Aug 5, 2013 at 5:48
1
  • I'd probably avoid producing nested arrays when parsing the array containing the keyword, and "flatten" it - but that is down to personal preference. I don't believe there's a significantly better way of accomplishing this with out-of-the-box JavaScript. Commented Aug 5, 2013 at 5:53

4 Answers 4

2

I would do something like

https://jsfiddle.net/denov/FXjXq/3/

var arr = [
 "cat dog mouse",
 "blue yellow green",
 "pizza burrito hamburger"
];
function isInString(needle, haystack) {
 return new RegExp('\\b' + needle + '\\b').test(haystack);
}
function checkForStringInArray(stringToFind, arr) {
 var inString = false;
 for(var i=0; i < arr.length; i++){ 
 inString = isInString(stringToFind, arr[i]);
 if(inString) break;
 }
 return inString;
}
var inString = checkForStringInArray('yellow', arr);
answered Aug 5, 2013 at 6:14

Comments

1

You can use regular expressions. I am giving you an example, although it is not the most efficient

function checkArray(str, arr){
 for(var i=0; i < arr.length; i++){
 if(str.match((".*" + arr[i].trim() + ".*").replace(" ", ".*")))
 return true;
 }
 return false;
}

Here I alter the string "key1 keyn" to ".*key1.keyn." so it could match those keys everywhere in the string. Have in mind that this will match them if they are part of another word. Good luck.

P.S. Learn regular expressions. They are pretty important in almost every language.

answered Aug 5, 2013 at 5:59

2 Comments

That regex will report "ab" as positive in itemDetails if you have "a b" in trackingList - I'm not sure that is wanted. Also, there's no need for the starting and trailing .* in the matching pattern; it'll do nothing but slow the regex down. I believe the OP's method is more precise, and faster.
Your regex method is slightly faster than what I have according to jsperf. I am using it with the modifications UweB suggested. Thanks.
1

This should work :

function checkArray(str, arr){
 for (var j = 0; j < arr.length;j++) {
 wordtab = splitTrackList(arr[j]);
 for(var i=0; i < tab.length; i++){
 if(str.indexOf(wordtab[i]) > -1)
 return true;
 }
 }
 return false;
}
answered Aug 5, 2013 at 6:07

Comments

0

Here is a solution with lambda expressions:

var itemDetails = '[alter] saber 1/8 figure unopened';
var trackingList = ['alter saber', 'magic', 'sword art'];
var trackingList2 = ['alter was', 'magic', 'sword art'];
if(trackingList.map(str => str.split(" ")).filter(arrtemp => arrtemp.filter(strin => itemDetails.indexOf(strin) > -1).length == arrtemp.length).length > 0) {
 console.debug("true");
} else {
 console.debug("false")
}
if(trackingList2.map(str => str.split(" ")).filter(arrtemp => arrtemp.filter(strin => itemDetails.indexOf(strin) > -1).length == arrtemp.length).length > 0) {
 console.debug("true");
} else {
 console.debug("false")
}

https://jsfiddle.net/wrz1m0b5/

The regex solution only works if words are in correct order.

answered Sep 17, 2016 at 6:25

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.