1

I want to pick random product objects from an array and place the info that they contain in four different containers. All the containers is hard coded in html and has the same class name, and I want to iterate through them.

Below you see the code, and that I'm using .each for this task, which of course doesn't work because every time the for loop runs it starts over again.

So, what is the best way to solve this?

function AddProducts(products) {

    for(var i = 0; i < 4; i++) {
        var number = Math.floor(Math.random() * products.length);

        $('.product').each(function(index) {
            $(this).find('h3').html(product[number].name);
        });
    }
}

    <div class="row span12">
      <ul class="thumbnails">
        <li class="span3 product">
          <div class="thumbnail padding">
            <h3>Product name</h3>
            <p>Description</p>
          </div>
        </li>
        <li class="span3 product">
          <div class="thumbnail padding">
            <h3>Product name</h3>
            <p>Description</p>
          </div>
        </li>
        <li class="span3 product">
          <div class="thumbnail padding">
            <h3>Product name</h3>
            <p>Description</p>
          </div>
        </li>
        <li class="span3 product">
          <div class="thumbnail padding">
            <h3>Product name</h3>
            <p>Description</p>
          </div>
        </li>
      </ul>
    </div>
holyredbeard
  • 19,619
  • 32
  • 105
  • 171
  • Um, the code does what you did describe, doesn't it? Or do you want to *pick four different items and place them each in one of the containers*? – Bergi Dec 15 '12 at 20:43
  • 1
    The selector in `$('.products')` would select nothing, as there is no class `products` in you HTML example. – feeela Dec 15 '12 at 20:56

3 Answers3

2

If you want to pick random products and place them into each container without duplicates, you have to shuffle the array first:

function shuffle(o)
{ //v1.0
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};

function AddProducts(products) 
{
    // this function modifies the array in-place
    // make a copy if you need to
    // products = shuffle(products.slice(0));
    shuffle(products);

    $('.product').each(function(i) {
        if (products[i]) {
            $(this).find('h3').html(products[i].name);
        }
    });
}

AddProducts([{name: 'foo'}, {name: 'bar'}, {name: 'baz'}, {name: 'dude'}]);

DEMO

The shuffle() function is taken from this question: How can I shuffle an array?

Also, one of your <li> elements has the wrong class .producer instead of .product. Okay, you've fixed that now :)

Community
  • 1
  • 1
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
1

Are you looking for something like this?

function AddProducts(products) {
    var selectedProducts = [];
    var producers = $('.producer');

    for(var i = 0; i < 4; i++) {
        var number = Math.floor(Math.random() * products.length);
        producers.eq(i).find('h3').html(product[number].name);
    }
}
koopajah
  • 23,792
  • 9
  • 78
  • 104
  • Thanks for the answer! I tried the code but it didn't work. What I want to do is to place four random products (with their data) in the four different containers. Shouldn't it be $('.producers').eq... btw? – holyredbeard Dec 15 '12 at 20:49
  • 1
    Try my updated version, I kind of messed up my copy and paste – koopajah Dec 15 '12 at 21:01
1

You don't need the for loop, when already using the jQuery .each() function.

var productTmp = product.slice(0);

$( '.product' ).each( function( index ) {

    var number = Math.floor( Math.random() * productTmp.length );

    $( this ).find( 'h3' ).html( productTmp[number].name );

    productTmp[number] = undefined;

} );

Instead of copying the original array and deleting the used products, you could use a condition or something, to remember which products of the list already were inserted. This should prevent multiple occurrences of one product in the list (as your are picking them randomly).

feeela
  • 29,399
  • 7
  • 59
  • 71
  • @holyredbeard This doesn't always use all the products you pass though. – Ja͢ck Dec 15 '12 at 21:11
  • @Jack How could it, if you only have four boxes, but fifty products? Or what did you mean? – feeela Dec 15 '12 at 21:14
  • @feeela See [this jsbin](http://jsbin.com/ubazux/1/) for an explanation of what I mean. It uses exactly four products and using your code it doesn't usually fill all containers. – Ja͢ck Dec 15 '12 at 21:16
  • 1
    @Jack I see. Don't thought of doubled random numbers or a check whether the requested element is available at that array position. – feeela Dec 15 '12 at 21:18