Reputation: 173
In a jQuery object, I'd like to shuffle all elements but the first. After different attempts I came up with this:
var $shuffled = $('.slide').slice(1).shuffle().end();
However this returns an empty object. How can I first select part of an object (slice), then shuffle it (custom function) and then set back the filter (end) so that $shuffled returns the whole object and not just a subset of it?
This is the shuffle code I use:
(function($){
$.fn.shuffle = function() {
var allElems = this.get(),
getRandom = function(max) {
return Math.floor(Math.random() * max);
},
shuffled = $.map(allElems, function(){
var random = getRandom(allElems.length),
randEl = $(allElems[random]).clone(true)[0];
allElems.splice(random, 1);
return randEl;
});
this.each(function(i){
$(this).replaceWith($(shuffled[i]));
});
return $(shuffled);
};
})(jQuery);
Upvotes: 0
Views: 98
Reputation: 173
Ok, I've found a simple solution myself. I didn't realize that .add() is what I'm looking for. Here's what it looks like now:
var $slides = $('.slide');
var $firstSlide = $slides.slice(0,1);
var $remainingSlides = $slides.slice(1).shuffle();
$slides = $firstSlide.add($remainingSlides);
Not as nice as a one-liner, but at least quite readable.
Upvotes: 1
Reputation: 4499
The commenter is right, I don't believe end()
is doing what you expect it to do.
Here is my solution, it could probably be optimized, but it completes the request at hand.
var $shuffled = [];
var allSlides = $('.slide');
var $first = allSlides.first();
$shuffled.push($first);
var $rest = allSlides.slice(1).shuffle().each(function(){
$shuffled.push($(this));
});
Here is a JSFiddle to Test the solution http://jsfiddle.net/gndgo6us/1/
On successive runs you can see the HTML change to show the shuffling.
Upvotes: 0