0

I have the an array of objects similar to this:

[
  {
    name: 'Apple',
    colors: ['red', 'green', 'yellow']
  },
  {
    name: 'Orange',
    colors: ['orange']
  }
]

I would like to shuffle the colors of each object. I am currently using the following code:

_.each(fruits, function (elem) {
  elem.colors = _.shuffle(elem.colors);
});

However, this code does not work with chaining, turns colors into an object, and requires an anonymous function that I think could be eliminated. Is there any way to make this code simpler?

PlasmaPower
  • 1,864
  • 15
  • 18

2 Answers2

2

That's how you implement it in a chainable way with lodash:

var r = _(a)
    .map(function(i) {
        return _.assign(i, { colors: _.shuffle(i.colors) });
    })
    .value();

JSFiddle: http://jsfiddle.net/bo8xf2as/

zerkms
  • 249,484
  • 69
  • 436
  • 539
  • 1
    I forked your Fiddle to display it in the output window instead, http://jsfiddle.net/tford/ku6cLL34/ – NYTom Apr 06 '15 at 02:17
  • It's generally not a good idea to mutate values inside `map()` as it introduces side-effects. If updating the values is the goal, you might as well use `each()` instead of `map()` since there's no need for a mapped array. If you really do want to map to a new array, I'd do something like `return _.defaults({ colors: _.shuffle(i.colors) }, i);` to avoid chaing the original object. – Adam Boduch Apr 06 '15 at 12:34
-2

Here is how you can simply do it using jinqJs to randomly shuffle the colors property array.

var data = [
  {
    name: 'Apple',
    colors: ['red', 'green', 'yellow']
  },
  {
    name: 'Orange',
    colors: ['orange']
  }
];


var result = jinqJs().from(data).select(function(row){
  row.colors = row.colors.sort(function() {return .5 - Math.random();});
  return row;
  });

document.body.innerHTML += '<pre>' + JSON.stringify(result, null, 2) + '</pre><br><br>';
<script src="https://rawgit.com/fordth/jinqJs/master/jinqjs.js"></script>
NYTom
  • 524
  • 2
  • 14
  • 2
    How is it better from what OP provided in the question? Your code is at least as twice as longer and requires another library to be included. – zerkms Apr 06 '15 at 02:06
  • This is a lot more complicated than my original example, there is no integrated shuffle and the anonymous function is kept. – PlasmaPower Apr 06 '15 at 02:06
  • I see, you want to reshuffle the items on the colors property, I was returning a random color from the colors property. The anonoymous function is not kept, it dies with the .select(). Yes, my code is 1 line longer, but im using jinqJs instead of underscore. – NYTom Apr 06 '15 at 02:11
  • You don't shuffle colors actually. – zerkms Apr 06 '15 at 02:17
  • 1
    That shuffle algorithm is not fair. For instance, it's twice as likely to end with 'yellow' as it is with 'red'. – Scott Sauyet Apr 06 '15 at 02:29
  • Scott can you explain why? Thanks – NYTom Apr 06 '15 at 02:38
  • Well, you can try it, just by iterating, say 10,000 times and counting how many of each one you get. Or you can see one of the [classic articles](http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html) or an [old SO post](http://stackoverflow.com/questions/962802/is-it-correct-to-use-javascript-array-sort-method-for-shuffling). It's not that it's difficult to explain, but it's a bit long for a comment! – Scott Sauyet Apr 06 '15 at 02:41
  • Thanks, Scott. Its interesting to find that Microsoft used the same algorithm. Then changed from using it because as someone pointed out in the SO post, it produced flawed results when tested against 100,000 items. – NYTom Apr 06 '15 at 02:48