2

I have a multi-dimensional array. I need some sort of loop to randomly pick a string in the array and check to see if that string contains a character. If it doesn't, then repeat until it finds one.

I wrote a for loop that checks the array for the string, BUT it starts from 0 and works its way through the array until it finds it. I need it randomly pick a string in the array...any help?

jsFiddle --> http://jsfiddle.net/hz2MZ/1/

jQuery

$(document).ready(function() {
var myarr = [{"Name":"Bob", "Char":"134"},
           {"Name":"Phil", "Char":"134"},
           {"Name":"Jane", "Char":"1"},
           {"Name":"Don", "Char":"4"},
           {"Name":"Dan", "Char":"2"},
           {"Name":"Jan", "Char":"12"},
           {"Name":"Bill", "Char":"24"},
           {"Name":"Sam", "Char":"14"},
           {"Name":"Jake", "Char":"23"},
           {"Name":"Ben", "Char":"3"}];


$('button').click(function() {
   for(var i = 0; i < myarr.length; i++) {
       if(myarr[i].Char.indexOf('2') !== -1) {
           alert("Name: " + myarr[i].Name + "\nChar: " + myarr[i].Char);
         return;
       } else {}
    } 
});

});
RobG
  • 142,382
  • 31
  • 172
  • 209
Sanya
  • 1,270
  • 5
  • 21
  • 47
  • 2
    [Shuffle the array first](http://stackoverflow.com/q/2450954/218196) and then iterate over it. – Felix Kling Jul 05 '13 at 21:41
  • 2
    *"I have a multi-dimensional array."* No you don't. You have an array of objects. – T.J. Crowder Jul 05 '13 at 21:43
  • @FelixKling: Your glance was better than mine, I think. – T.J. Crowder Jul 05 '13 at 21:48
  • I think making a copy of the array and shuffling it (or shuffling the original if there's no need to retain a specific order) is the best plan because then you stop either when you find a match or when you've checked every item. – nnnnnn Jul 05 '13 at 21:52
  • _"that empty branch is absolutely irrelevant"_ - Exactly my point. It's needless clutter, both as part of a question here and in real-world programs. – nnnnnn Jul 05 '13 at 21:53
  • @Stano - What? You said it was "absolutely irrelevant", and now you say "you solve it as if it was relevant"? Are you telling me to pay attention to it or ignore it? It's not an error, but I wouldn't go so far as to say there's "_nothing_ wrong" about completely redundant code that isn't needed because it is completely redundant and doesn't do anything so isn't necessary due to its redundanticity. – nnnnnn Jul 05 '13 at 22:11
  • @nnnnnn Yes I meant to ignore it. When I create an empty branch it's intended to be "reserved for future use" or just add there a short comment describing its possible usage. So imo it's ok. Have a good time ;-) – Stano Jul 05 '13 at 22:52

2 Answers2

3

My solution

$('button').click(function () {
        var found = false;

        while (!found) {
            var randomIndex = Math.floor(Math.random() * myarr.length);
            if (myarr[randomIndex].Char.indexOf('2') !== -1) {
                alert("Name: " + myarr[randomIndex].Name + "\nChar: " + myarr[randomIndex].Char);
                found = true;
            } else {}

        }
    });

edit

Updated endless loop problem

$('button').click(function () {
    var found = false;
    var maxRandom = 20;
    var currentRandom = 0;

    while (!found && currentRandom < maxRandom) {
        var randomIndex = Math.floor((Math.random() * myarr.length));
        currentRandom++;

        if (myarr[randomIndex].Char.indexOf('2') !== -1) {
            alert("Name: " + myarr[randomIndex].Name + "\nChar: " + myarr[randomIndex].Char);
            found = true;
        } else {}
    }
}
Johan
  • 8,068
  • 1
  • 33
  • 46
  • 2
    Note that this will be an endless loop if the character searched for isn't in any of the array items. – nnnnnn Jul 05 '13 at 21:49
  • *"I see TJ beat me too it"* No, you caught the essential bit I missed, +1. I'd remove the entirely pointless `else {}` though. :-) – T.J. Crowder Jul 05 '13 at 21:49
  • @nnnnnn there are multiple ways of handling that. The OP can decide which is best. He asked for a random way to select something, not a 100% bullet proof solution. This is a step in the right direction. – Johan Jul 05 '13 at 21:51
  • @T.J.Crowder I only noticed a while later, that you missed the loop. Also left the else, as the OP might want to add stuff :) – Johan Jul 05 '13 at 21:51
  • You could set `var maxRandom = myarr.length;` then decrease `it--` `while(maxRandom>0)` and at each step swap the last item with the randomly choosen one. Then it could check all existing fields. – Stano Jul 05 '13 at 22:10
  • That's a good idea @Stano, together with using `maxRandom` as the limit on the random number generated - except you'd need to swap the random element with the one at index `maxRandom - 1`, not with the last item in the array (otherwise you'd keep swapping the already-checked items back into the "active" range). – nnnnnn Jul 05 '13 at 22:17
  • It's the same as Felix proposed at the beginning of this question. http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript/#6274398 – Stano Jul 05 '13 at 22:37
1

One approach is to copy the array, then randomly splice one member from the copy and check for the required value:

function randomValueByChar(arr, c) {
  var a = arr.slice && arr.slice();
  var i = a.length || 0;
  var t;

  while (i--) {
    t = a.splice(Math.random() * i | 0, 1);
    if (t[0].Char.indexOf(c) != -1) return t;  
  }
}

Another approach is to create an array of the indexes (e.g. [0,1,2,3…]), then randomly splice one value at a time and use it as an index to retrieve a value from the array. Both approaches will not have an infinite loop and will visit each member a maximum of once.

RobG
  • 142,382
  • 31
  • 172
  • 209