Dale
Dale

Reputation: 580

Checking/Iterating Multi-dimensional arrays in jQuery

I have the following array:

{
  quiztitle: "Name the US Presidents",
  presidents: [
        {
          president_name: "George Washington",
          number: "1",
          imgurl: "c-1gw.jpg",
          answer_variations: [
                              "Washington"
                             ]
         },
         {
          president_name: "John Quincy Adams",
          number: "6",
          imgurl: "c-6ja.jpg",
          answer_variations: [
                               "Adams",
                               "John Adams"
                             ]
          }, .... ect

How do I access the answer variations array and compare the contents against a submitted value?

I currently have this code for checking the presidents:

var answer = $('.presidentRow input').val().toLowerCase();
var correct = false; 
$.each(data.presidents, function(i, president) {
if ( president.number == questionNumber && president.president_name.toLowerCase() === answer) {
                            correct = true;
                            return false;
                        }
                    });

This code takes the question number and checks the users submitted value against the presidents name. If its correct it sets the variable true and I can work with that to produce a result. How can I check the submitted answer against the variations aswell?

Thanks

Upvotes: 0

Views: 58

Answers (4)

fuyushimoya
fuyushimoya

Reputation: 9813

  1. Create a list to hold the names and its all variations in lowercase. Use $.merge to create list, then use $.map to form them to lowercase.

  2. If the answer is any of them, answer is correct. Use $.inArray to find the index, and if index >= 0, the answer is in the list, so its correct.

var answer = $('.presidentRow input').val().toLowerCase();
var questionNumber = $('#qNum').val();
var correct = false; 
$.each(data.presidents, function(i, president) {
  if ( president.number == questionNumber) {
    // Put all possible name answers into an array.
    var nameVairations = 
      $.merge([president.president_name], president.answer_variations);

    // .toLowercase all answers
    nameVairations = $.map(nameVairations, function(name) {
      return name.toLowerCase();
    });

    // Check if the answer appears in the list
    if ($.inArray(answer, nameVairations) >= 0) {
      correct = true;
      return false;
    }
  }
});

You can also achieve the same result with vanilla js array functions .concat, .map, .indexOf

Upvotes: 0

Alex Nikulin
Alex Nikulin

Reputation: 8689

var answer = answer.toLowerCase().replace(/\s+/," ") // replace multiple spaces by single space and lower the case
var correct = false; 
var president = data.presidents.find(function(president){return president.number == questionNumber;})
if(president){
   var variationsArr = president.answer_variations.concat([president.president_name])
   correct = ("|" + variationsArr.join("|").toLowerCase() + "|").indexOf("|" + answer + "|") > -1; 
}

Upvotes: 0

MinusFour
MinusFour

Reputation: 14423

So basically, iterate the presidents array until we find that the number of its president is equal to the question number. Then test the answer against the president name, if not... try to find it in the answer_variations arrray.

var answer = $('.presidentRow input').val().toLowerCase();
var presidents = data.presidents;
var correct = presidents.some(function(president) {
    if (president.number == questionNumber) {
      if (answer == president.president_name.toLowerCase()) {
        return true;
      } else {
        return president.answer_variations.some(function(validAnswer) {
          console.log(validAnswer.toLowerCase());
          if (answer == validAnswer.toLowerCase()) {
            return true;
          }
        });
      }
    }
  });

I don't know how you get questionNumber.

Small Test

var data = {
  quiztitle: "Name the US Presidents",
  presidents: [{
    president_name: "George Washington",
    number: "1",
    imgurl: "c-1gw.jpg",
    answer_variations: [
      "Washington"
    ]
  }, {
    president_name: "John Quincy Adams",
    number: "6",
    imgurl: "c-6ja.jpg",
    answer_variations: [
      "Adams",
      "John Adams"
    ]
  }]
};

function presidentTest(answer, questionNumber) {
  var answer = answer.toLowerCase();
  return data.presidents.some(function(president) {
    if (president.number == questionNumber) {
      if (answer == president.president_name.toLowerCase()) {
        return true;
      } else {
        return president.answer_variations.some(function(validAnswer) {
          console.log(validAnswer.toLowerCase());
          if (answer == validAnswer.toLowerCase()) {
            return true;
          }
        });
      }
    }
  });
}

/**** TEST *****/
document.getElementById('results').innerHTML += '\n' + presidentTest('george Washington', 1);
document.getElementById('results').innerHTML += '\n' + presidentTest('wachington', 1);
document.getElementById('results').innerHTML += '\n' + presidentTest('adams', 6);
document.getElementById('results').innerHTML += '\n' + presidentTest('john adams', 6);
<pre id="results"></pre>

Upvotes: 0

Lin Yuan
Lin Yuan

Reputation: 538

Another way of compare you can try~

var answer = $('.presidentRow input').val().toLowerCase();
var correct = false;
$.each(data.presidents, function(i, president) {
    if ( president.number == questionNumber) {
        if(president.president_name.toLowerCase() === answer){
            correct = true;
        }else if((','+ president.answer_variations.join().toLowerCase()+',').indexOf(','+answer+',')!=-1){
            correct = true;
        }
        return false;
    }
});

EDIT

Use Array.join() make variations as coma seperated string and you can simple use String.indexOf() to check if the answer exists or not.

Add ',' make the answer will fit the correct variations option.

Upvotes: 1

Related Questions