Home > front end >  How to make an if statement run for the entire For loop execution without going to else statement?
How to make an if statement run for the entire For loop execution without going to else statement?

Time:10-03

Continued from the question it seems My code always outputs the else statement even when the if statement is true, i have assumed it is because the for loop is not getting executing completely before being denied that input.value is not available in data[i].s, therefore the output is always "I dont understand" even when input.value = "hi"

How to solve this?

function senda() {

  var input = document.querySelector('input'),
    send = document.createElement('p'),
    recv = send.cloneNode(true),
    data = [{
      "s": "hi",
      "r": "hello"
    }, {
      "s": "whats up",
      "r": "alright"
    }];

  send.innerText = input.value;
  document.body.appendChild(send);
  for (var i = 0; i < data.length; i  ) {
    if (input.value == data[i].s) {
      recv.innerText = data[i].r;
      document.body.appendChild(recv);
    } else {
      recv.innerText = "I don't understand";
      document.body.appendChild(recv);
    }
  }
}
<input>
<button onclick="senda()">-></button>

CodePudding user response:

Your code is working fine.

But it is not working as you thinking.

data has 2 obejct: And first loop

if it equals to hi and prints hello not works else statement

and second loop it is not equal to hi so this time else statement works

so you must break if it finds equal value

like below

    function senda() {

      var input = document.querySelector('input'),
        send = document.createElement('p'),
        recv = send.cloneNode(true),
        data = [{
          "s": "hi",
          "r": "hello"
        }, {
          "s": "whats up",
          "r": "alright"
        }];

      send.innerText = input.value;
      document.body.appendChild(send);
      var isInputInData = false;
      for (var i = 0; i < data.length; i  ) {
        if (input.value == data[i].s) {
          recv.innerText = data[i].r;
          isInputInData = true;
          break;
        }
      }
      if(!isInputInData) recv.innerText = "I don't understand";

      document.body.appendChild(recv);
    }
  <input>
  <button onclick="senda()">-></button>

CodePudding user response:

Please add one line code.

When the input vale is equal to data[i].s please add "i = data.length;"

function senda() {
    var input = document.querySelector('input'),
        send = document.createElement('p'),
        recv = send.cloneNode(true),
        data = [{
            "s": "hi",
            "r": "hello"
        }, {
            "s": "whats up",
            "r": "alright"
        }];

    send.innerText = input.value;
    document.body.appendChild(send);
    for (var i = 0; i < data.length; i  ) {
        if (input.value === data[i].s) {
            recv.innerText = data[i].r;
            document.body.appendChild(recv);
            i = data.length;
        } else {
            recv.innerText = "I don't understand";
            document.body.appendChild(recv);
        }
    }
}
<input>
<button onclick="senda()">-></button>

CodePudding user response:

Your issue is that your for loop will keep running for all entries in your data array. That means that even if a match is found, the loop continues to run, which causes the innerText to be replaced until the last item.

There is a simply way to do this: all you want is to check whether the user input matches any value in the nested s key in the array of object. You can use Array.prototype.findIndex to retrieve the index that matches your requirement.

If the index is more than -1, then you know you have a match. Otherwise you can just return the fallback statement, e.g.:

const foundIndex = data.findIndex(d => d.s === input.value);
if (foundIndex > -1) {
  recv.innerText = data[foundIndex].r;
} else {
  recv.innerText = "I don't understand";
}
      
document.body.appendChild(recv);

For simplicity, you can condense this into a one-liner:

const foundIndex = data.findIndex(d => d.s === input.value);
recv.innerText = foundIndex > -1 ? data[foundIndex].r : "I don't understand";

Of course, this solution works only if the nested s values are unique in your array. Otherwise you will always get the first occurring matching instance.

There are some additional tips:

  • Don't use inline JS bindings. Use addEventListener instead
  • You might want to convert input.value to lowercase so that we can perform a case-insensitive match
  • Store your data outside of the function: it is a constant and don't have to be redeclared every time the function is invoked

See proof-of-concept below with additional tips applied:

const data = [{
  "s": "hi",
  "r": "hello"
}, {
  "s": "whats up",
  "r": "alright"
}];

function senda() {
  const input = document.querySelector('input');
  const send = document.createElement('p');
  const recv = send.cloneNode(true);

  send.innerText = input.value;
  document.body.appendChild(send);

  const foundIndex = data.findIndex(d => d.s.toLowerCase() === input.value.toLowerCase());
  recv.innerText = foundIndex > -1 ? data[foundIndex].r : "I don't understand";

  document.body.appendChild(recv);
}

document.querySelector('button').addEventListener('click', senda);
<input>
<button>-></button>

  • Related