The Codesee
The Codesee

Reputation: 3783

Unable to determine if a string contains a word from an array

I'm trying to determine if a string contains a word from an array by using jQuery's inArray function, which is shown here https://stackoverflow.com/a/18867667/5798798

In my example below, it should print 'hi' to the console twice as the word 'Hello' is in the string twice and is in the array, however it doesn't.

var array = ["Hello", "Goodbye"];

a = document.getElementsByClassName("here");

for (i = 0; i < a.length; i++) {
  itag = a[i].getElementsByTagName("i")[0];
  if (jQuery.inArray(itag.innerHTML, array) !== -1) {
    console.log('hi');
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="here"><i><a href="link.php">Hello</a> | <a href="link2.php">Example</a></i>
</div>

<div class="here"><i><a href="link.php">Hey</a> | <a href="link2.php">Hello</a></i>
</div>

Upvotes: 7

Views: 489

Answers (5)

Denis Rybalka
Denis Rybalka

Reputation: 1871

The most elegant way to find it is obviously a RegExp

    var array = ["Hello", "Goodbye"];

    var a = document.getElementsByClassName("here");
    Array.prototype.forEach.call(a, function( node ) {
      var itag = node.getElementsByTagName("i")[0]
      if (itag.innerHTML.match(new RegExp(array.join('|'), 'gi'))) {
        console.log('hi')
      }
   });

Upvotes: 0

Suresh Atta
Suresh Atta

Reputation: 121998

You are checking whether innerHTML is in the array or not.

Actually you should check whether the inner html consists of any of the array element.

So if you convert the above statement to code, it should be

var array = ["Hello", "Goodbye"];

a = document.getElementsByClassName("here");

for (i = 0; i < a.length; i++) {
   debugger;
   var itag = a[i].getElementsByTagName("i")[0];
   for (var k in array) {
    if(itag.innerHTML.indexOf(array[k]) > -1){
    console.log('hi');
    }
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="here"><i><a href="link.php">Hello</a> | <a href="link2.php">Example</a></i>
</div>

<div class="here"><i><a href="link.php">Hey</a> | <a href="link2.php">Hello</a></i>
</div>

Upvotes: 2

Suren Srapyan
Suren Srapyan

Reputation: 68635

Change inArray function with array.some(text => itag.textContent.includes(text)).

Declare all variables via var or const or let.

Instead of innerHTML use textContent. This will not try to parse the content and will work faster.

var array = ["Hello", "Goodbye"];

var a = document.getElementsByClassName("here");

for (var i = 0; i < a.length; i++) {
    var itag = a[i].getElementsByTagName("i")[0];
    var textContent = itag.textContent;
    if(array.some(text => textContent.includes(text))) {
       console.log(textContent);
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="here"><i><a href="link.php">Hello</a> | <a href="link2.php">Example</a></i>
</div>

<div class="here"><i><a href="link.php">Hey</a> | <a href="link2.php">Hello</a></i>
</div>

Upvotes: 7

Thomas
Thomas

Reputation: 12637

Not really an answer, rather an extension to @SurenSrapyan answer with further improvements to your code.

Instead of dealing with this nested getElementsByTagName and getElementsByClassName here, you can write this as a single CSS-selector targeting the nodes: document.querySelectorAll('.here i:first-of-type');

And innerHTML and textContent are both getter that create the value as you fetch it by traversing the DOM. So better store the value once in a variable, than fetching it inside a loop where it has to be created over and over again; well, unless the value might have changed.

var words = ["Hello", "Goodbye"];
var nodes = document.querySelectorAll('.here i:first-of-type');

for(var i=0; i<nodes.length; ++i){
    var node = nodes[i];
    var textContent = node.textContent;
    if(words.some(word => textContent.includes(word))) {
       console.log(node, textContent);
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="here">
  <i><a href="link.php">Hello</a> | <a href="link2.php">Example</a></i>
  <i>Hello, not matching me, as I'm not the first &lt;i&gt; in .here</i>
</div>

<div class="here"><i><a href="link.php">Hey</a> | <a href="link2.php">Hello</a></i>
</div>

Upvotes: 0

charlietfl
charlietfl

Reputation: 171679

Simpler approach is loop over the words array and use :contains selector

var array = ["Hello", "Goodbye"],
    $links = $('.here i a');

$.each(array, function(i, word){
  $links.filter(':contains(' + word +')').addClass('word-match');
})
.word-match {color:red}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="here"><i><a href="link.php">Hello</a> | <a href="link2.php">Example</a></i>
</div>

<div class="here"><i><a href="link.php">Hey</a> | <a href="link2.php">Hello</a></i>
</div>

Upvotes: 0

Related Questions