24

How can I select the first 5 random elements

<ul> <li>First</li> <li>Second</li> <li>Third</li> ... <li>N</li> </ul> 

I'm using this plugin:

alert($("li:random").text()); 

but it takes all random elements. I only want the first 5.

Is there another way to do the same thing?

3
  • Can you wrap a div around the first five server-side, then use li #first-five:random ? Commented Nov 19, 2009 at 15:39
  • I am not aware of jQuery supporting the ":random" pseudo-selector, how do you add this functionality and what's the code logic behind it ? Commented Nov 19, 2009 at 16:10
  • blog.mastykarz.nl/jquery-random-filter but if do You can show me another way, how to select 5 random element , will be awesome Commented Nov 19, 2009 at 16:16

6 Answers 6

52

Here's how to get 5 random elements from a jQuery selection, no need of plugins!

randomElements = jQuery("li").get().sort(function(){ return Math.round(Math.random())-0.5 }).slice(0,5) 

At this point you have 5 DomElements that have been selected randomly from all the LIs that jQuery returned

You can then do whatever you like with them,
e.g change their color:

$(randomElements).css("color","red") 

or display their combined text contents:

$(randomElements).text() 
Sign up to request clarification or add additional context in comments.

5 Comments

+1, though I'm curious as to why you spelt "random" consistently correctly in the text, and consistently incorrectly in the code snippets... :-)
The general idea is good, but you shouldn't shuffle an array like that. Sorting is an inefficient way to shuffle an array, and an inconsistent comparison can cause problems (even potentially causing the sort to loop indefinitely). It's better to use a Fisher-Yates shuffle (en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle).
That won't get you a randomly sorted array. Here's an article about it (it's Objective-C, but shouldn't matter) cocoawithlove.com/2010/06/…
As Georg pointed out, this will not produce a random set as at least one pivot element (most probably the one in the middle) will be used when (quick)sorting the array. Georg's link was a good read! Downvoting.
This is bad. Selecting X random elements is O(1), while sorting whole collection takes O(n log n) at best.
8

Using the Fisher-Yates shuffle I have created a small script for this purpose. This is done by first creating a randomly shuffled and sliced copy of the array of jQuery elements, and then filtering out all elements that do not exist in both arrays.

You can read about it at http://www.afekenholm.se/jquery-rand. Here's the script:

/** * jQuery.rand v1.0 * * Randomly filters any number of elements from a jQuery set. * * MIT License: @link http://www.afekenholm.se/license.txt * * @author: Alexander Wallin (http://www.afekenholm.se) * @version: 1.0 * @url: http://www.afekenholm.se/jquery-rand */ (function($){ $.fn.rand = function(k){ var b = this, n = b.size(), k = k ? parseInt(k) : 1; // Special cases if (k > n) return b.pushStack(b); else if (k == 1) return b.filter(":eq(" + Math.floor(Math.random()*n) + ")"); // Create a randomized copy of the set of elements, // using Fisher-Yates sorting r = b.get(); for (var i = 0; i < n - 1; i++) { var swap = Math.floor(Math.random() * (n - i)) + i; r[swap] = r.splice(i, 1, r[swap])[0]; } r = r.slice(0, k); // Finally, filter jQuery stack return b.filter(function(i){ return $.inArray(b.get(i), r) > -1; }); }; })(jQuery); 

Comments

8

Get a random number index, 1-5, and get the child of the ul with that index. Like so:

var index = Math.floor(Math.random() * 5) + 1; // nth-child indices start at 1 alert($("ul:nth-child(" + index + ")").text()); 

3 Comments

Oh, this is completely wrong. I read the question as requesting one random element out of the first five, not five random elements from the set. I think I need sleep! :D
Got here by searching exactly for this kind of solution. So answering to misread qestions is not always bad :)
Math.random() returns a value in [0,1) -- that is, including 0 but excluding 1. So there's the possibility (albeit rare) that index will be 0. To avoid this, use var index = Math.floor(Math.random() * 5) + 1;.
2
 jQuery.jQueryRandom = 0; jQuery.extend(jQuery.expr[":"], { random: function(a, i, m, r) { if (i == 0) { jQuery.jQueryRandom = Math.floor(Math.random() * r.length); }; return i == jQuery.jQueryRandom; } }); 

Comments

0
$("li:lt(5):random").text() 

1 Comment

But it takes always the first 5 (
-1

Why not just do this, it seems pretty efficient:

jQuery('li:random').slice(0, 5); 

1 Comment

Probably because jQuery has no :random selector [anymore]?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.