0

I have the following fiddle using test data, and I am looking through data using $.each

I can loop through no problem, but I want to loop through the data, and then get 3 objects from it at random.

Any tips or tricks would help:

https://jsfiddle.net/inkedraskal/pah44qv6/

$.each(testData,function(x, blah){
    //console.log(blah._id);

  //this gets each objects id & picture, but I want to get 3 random objects, and their corresponding data
  var activeValue = blah._id,
        pictureValue = blah.picture;


  var markUp = '';

  markUp += activeValue + pictureValue;

  console.log(markUp);
});

with the question below, they need to be unique**

3
  • Must the three random items be unique? Commented Sep 24, 2016 at 1:28
  • Oh good question, yes they must be unique Commented Sep 24, 2016 at 1:32
  • Are looking only for a solution that uses $.each? Is there a specific reason for that? You can check my answer, let me know if it OK. Commented Sep 24, 2016 at 2:19

4 Answers 4

2

The function in the snippet below gets an array and a number (X) of items and returns a new array with X unique random items from the original array:

function getRandomItems(arr, items) {
  var ret = [];
  var indexes = [];
  var arr_length = arr.length;
  
  // If we don't have enough items to return - return the original array
  if (arr_length < items) {
    return arr;
  }
  
  while (ret.length < items) {
    i = Math.floor(Math.random() * arr_length);
    if (indexes.indexOf(i) == -1) {
      indexes[indexes.length] = i;
      ret[ret.length] = arr[i];
    }
  }
  return ret;
}

arr = ['a', 'b', 'c', 'd', 'e']
console.log(getRandomItems(arr, 2))

You can also add the function to the Array.prototype if you want to use it on every Array in your code as a "native" function:

Array.prototype.getRandomItems = function(items) {
  var ret = [];
  var indexes = [];
  var arr_length = this.length;
  
  // If we don't have enough items to return - return the original array
  if (arr_length < items) {
    return this;
  }
  
  while (ret.length < items) {
    i = Math.floor(Math.random() * arr_length);
    if (indexes.indexOf(i) == -1) {
      indexes[indexes.length] = i;
      ret[ret.length] = this[i];
    }
  }
  return ret;
}

arr1 = ['a', 'b', 'c', 'd', 'e']
arr2 = ['aaa', 'bbb', 'ccc', 'ddd', 'eee']

console.log(arr1.getRandomItems(1))
console.log(arr1.getRandomItems(2))
console.log(arr2.getRandomItems(3))
console.log(arr2.getRandomItems(4))

Sign up to request clarification or add additional context in comments.

Comments

1

We can create getRandomEntry() function which will return one of the array's elements by using Math.random() function. We'll create a loop which will take random entry every time it iterates.

function getRandomEntry() {
  return testData[Math.round(Math.random() * (testData.length - 1))];
}

for (var i=0; i<3; i++) {
  var entry = getRandomEntry();
  console.log(entry._id, entry.picture);
}

If you need an unique entry every time. You can keep random entries in separate array and check if new one is unqiue.

var randomEntries = [];

function getRandomEntry() {
  return testData[Math.round(Math.random() * (testData.length - 1))];
}

function entryExists(entry) {
  return randomEntries.indexOf(entry) > -1;
}

for (var i=0; i<3; i++) {
  var entry;

  do {

    entry = getRandomEntry();

  } while(entryExists(entry))

  randomEntries.push(entry);
  console.log(entry._id, entry.picture);
}

2 Comments

This will fail the they need to be unique requirement
Edited the answer.
1

You could use a recursive function like the below.

Note that this implementation prevents duplicates in the results

function getRandomObjects(array,selected,needed){
    /*
     *@param array array The array to pull from
     *@param selected array The array of results pulled so far
     *@param needed int The number of results we want
     */
    var length = array.length;
    var num = Math.floor(Math.random() * length) + 1; // get random number in bounds of array
    var exists=false; // make sure we didnt already pick this object
    $.each(selected,function(i,obj){
        if(obj.index==num)exists=true;
    })
    if(exists) getRandomObjects(array,selected,needed); // get a new one if this was a duplicate
    else selected.push(array[num]);
    if(selected.length!=needed) return getRandomObjects(array,selected,needed); // get another object if we need more
    else return selected; // return the final result set
}




var testData = [
  {
    "_id": "57e5d1a90c4206b128cd8654",
    "index": 0,
    "guid": "1f3269fc-0822-4c5a-9c52-8055155b407e",
    "isActive": true,
    "balance": "$3,026.95",
    "picture": "http://placehold.it/32x32"
  },
  {
    "_id": "57e5d1a9a986ccb2f41cf7b9",
    "index": 1,
    "guid": "a6b726b6-6466-4e48-8697-1c6bd7b1c79e",
    "isActive": true,
    "balance": "$2,642.74",
    "picture": "http://placehold.it/32x32"
  },
  {
    "_id": "57e5d1a9f98f8b2f6880de32",
    "index": 2,
    "guid": "e7d736cc-19e0-4bcb-8d0a-4d17442d8cee",
    "isActive": true,
    "balance": "$3,341.64",
    "picture": "http://placehold.it/32x32"
  },
  {
    "_id": "57e5d1a9e40ded5b017e45cd",
    "index": 3,
    "guid": "64230ca8-05c0-4c39-a931-794172475a32",
    "isActive": true,
    "balance": "$2,196.13",
    "picture": "http://placehold.it/32x32"
  },
  {
    "_id": "57e5d1a90cc30be769a06d7c",
    "index": 4,
    "guid": "d6618b78-753a-4ad0-bc14-3687d0b99196",
    "isActive": true,
    "balance": "$1,611.62",
    "picture": "http://placehold.it/32x32"
  },
  {
    "_id": "57e5d1a92481a43f50607415",
    "index": 5,
    "guid": "35ec8186-9494-4f89-ab89-bed7f39872c3",
    "isActive": true,
    "balance": "$3,148.87",
    "picture": "http://placehold.it/32x32"
  },
  {
    "_id": "57e5d1a9164f17c558ba7ce1",
    "index": 6,
    "guid": "244970a0-1ce2-405a-8d69-c7903f9bf5eb",
    "isActive": false,
    "balance": "$3,758.13",
    "picture": "http://placehold.it/32x32"
  },
  {
    "_id": "57e5d1a95afde31c5cf592a8",
    "index": 7,
    "guid": "aa30c82d-dd2b-420c-8b30-7d66cec8d10b",
    "isActive": true,
    "balance": "$1,311.40",
    "picture": "http://placehold.it/32x32"
  }
]


var randomObjects=getRandomObjects(testData,[],3);

console.log(randomObjects);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Comments

0

You can do this

var items = [1, 2, 3, 4, 5];
var newItems = [];

for(var i = 0; i < 3; i++) {
    var idx = Math.floor(Math.random() * items.length);
    newItems.push(items[idx]);
    items.splice(idx, 1);
}

console.log(newItems);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.