1

I'm trying to set select a random item from an array. Once selected, it needs to be removed from the array so it does not get selected again. Finally, once the array is emptied, the process needs to restart. I'm trying to do this using sessionStorage because I need to keep track of which random item gets selected.

// Get array from sessionStorage
myArray = JSON.parse(sessionStorage.getItem("array"));

// If array does not exist in sessionStorage, set it
if (myArray === null) {
  sessionStorage.setItem("array", JSON.stringify(["apple", "orange", "banana"]));

// If array exists in sessionStorage, use it to get random item and empty it from array
} else {
  var randomItem = myArray[Math.floor(Math.random() * myArray.length)];
  console.log(randomItem);
  console.log(myArray.splice(randomItem, 1));
}

My JSFiddle can be seen here.

Edit: Updated my work here. Eventually the array is cleared out and restarts.

kaoscify
  • 1,743
  • 7
  • 37
  • 74
  • 4
    Did you have a question? –  Aug 10 '16 at 20:02
  • Uh, yeah - what's the problem here? – VLAZ Aug 10 '16 at 20:03
  • `.splice()` wants you to pass the *index* in the array as the 1st parameter, not the value. – gen_Eric Aug 10 '16 at 20:04
  • 1
    The `splice` function needs the index of the element to remove. `var index=Math.floor(...), randomItem=myArray[index]; myArray.splice(index,1);` **Edit**: You could also just do `var randomItem=myArray.splice(Math.floor(...),1)[0];` since `splice` will return an array containing the removed elements. `[0]` allows you to get the first one. @RocketHazmat whoops :) – blex Aug 10 '16 at 20:04
  • @blex: `splice` not `slice` :P – gen_Eric Aug 10 '16 at 20:04
  • 2
    Why not fisher yates shuffle() the array once and the pop() off items as you need them? – JonSG Aug 10 '16 at 20:04
  • @JonSG Thanks, I did experiment with Fisher-Yates, but did not know about pop(), looking into it. – kaoscify Aug 10 '16 at 20:06

2 Answers2

2

This probably will not run in this sandbox (use of localstore), but I think it should work if you tried it.

// -------------------------------
// see: http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
// -------------------------------
function _shuffle (array) {
  for (var i = array.length - 1; i > 0; i--) {
      var j = Math.floor(Math.random() * (i + 1));
      var temp = array[i];
      array[i] = array[j];
      array[j] = temp;
  }
  return array;
}
// -------------------------------

// -------------------------------
// Get the next "random" item.
// -------------------------------
var randomItem  = (function(allItems){
  var _key = "array";
  var _currentItems = [];

  try {
    _currentItems = JSON.parse(localStorage.getItem(_key) || "[]");
  } catch (e) {
    _currentItems = [];
  }

  if (!Array.isArray(_currentItems) || _currentItems.length === 0 ) {
    console.log("resetting");
    _currentItems = _shuffle(allItems.slice());
  }

  var _selectedItem = _currentItems.pop();
  localStorage.setItem(_key, JSON.stringify(_currentItems));

  return _selectedItem;
})(["apple", "orange", "banana"]);
// -------------------------------

console.log(randomItem);

A more bare bones version [ with _shuffle() from above ] might be just:

var nextItem  = (function(all){
  var _key = "array";
  var _current = JSON.parse(localStorage.getItem(_key) || "[]");
  if (_current.length === 0) { _current = _shuffle(all.slice()); }

  var _selected = _current.pop();
  localStorage.setItem(_key, JSON.stringify(_current));

  return _selected;
})(["apple", "orange", "banana"]);
JonSG
  • 10,542
  • 2
  • 25
  • 36
  • Thanks JonSG. This is probably more robust than mine. Let me try it out. I updated my question with a solution I was working on. – kaoscify Aug 10 '16 at 20:52
  • Sure thing. I added some extra checks to make things a little less brittle but you could take the try/catch out easily enough. Good luck – JonSG Aug 10 '16 at 20:56
1

I think the problem you are having is caused by the fact that you are passing the value you get from the array the the splice() function when it is actually expecting an index. Checkout the docs page. so what you would do instead is:

// Get array from sessionStorage
myArray = JSON.parse(sessionStorage.getItem("array"));

// If array does not exist in sessionStorage, set it
if (myArray === null) {
  sessionStorage.setItem("array", JSON.stringify(["apple", "orange", "banana"]));

// If array exists in sessionStorage, use it to get random item and empty it from array
} else {

  //get random index of item to remove
  var randomIndex = Math.floor(Math.random() * myArray.length);

  //remove the item at that index
  myArray.splice(randomIndex, 1); //this returns an array containing the removed item, so you can capture it if you like
}
Duly Kinsky
  • 996
  • 9
  • 11
  • How can I get the updated array with the removed item? It would be nice to be able to cycle through the array until all items are removed. – kaoscify Aug 10 '16 at 20:34
  • myArray is updated after making the call: myArray.splice(randomIndex, 1); if what was picked was index 0, now myArray would be ["orange", "banana"] – Duly Kinsky Aug 10 '16 at 20:36