0

I’m using Lodash to make manipulating objects easier. I have an object with three nested objects inside. I’d like to iterate through these, concatenating all of their respective children together in all possible combinations, whilst only using one per list.

My object looks like this:

{
  "list_1": {
    "1": ".cat-3",
    "2": ".cat-5",
    "3": ".cat-7"
  },
  "list_2": {
    "1": ".eyes-blue",
    "3": ".eyes-brown"
  },
  "list_3": {
    "1": ".jazz",
    "2": ".commercial",
    "3": ".hip-hop"
  }
}

The output I’d like to get is:

.cat-3.eyes-blue.jazz
.cat-3.eyes-blue.commercial
.cat-3.eyes-blue.hip-hop

The order isn't crucial. What's crucial is that only one value from each list_ object is used in the string. So this, for example, would be fine:

.eyes-blue.jazz.cat-3
.eyes-blue.cat-3.commercial
.hip-hop.eyes-blue.cat-3

And some more examples:

.cat-3.eyes-brown.jazz
.cat-5.eyes-brown.hip-hop
.cat-7.eyes-blue.hip-hop
gosseti
  • 965
  • 16
  • 40
  • You can't guarantee the order the properties are returned using methods like *for..in* or *Object.keys* (other than the order of those two will be the same) therefore unless you hard code the names, or apply a sort for each set of keys, you might get the combinations in any order. – RobG Oct 28 '14 at 11:36
  • Excellent point there. The order isn’t crucial. I have amended my question to clarify this. – gosseti Oct 28 '14 at 11:49
  • It seems you want to have permutation from 3 sets taken one from each set – Amitesh Oct 28 '14 at 12:11
  • I’ve amended the question to explain things a bit better. – gosseti Oct 28 '14 at 12:32

2 Answers2

2

Store the values of the property objects as an array of arrays:

var arrayOfArrays = [];

_.each(obj, function(item, key) {
  var itemVals = [];
  _.each(item, function(item2, key2) {
    itemVals.push(item2);
  });
  arrayOfArrays.push(itemVals);
});

Implement the suffle() function as described here: https://stackoverflow.com/a/2450976/2193416

Implement a function to get a random array element:

function randomElement(array) {
  return array[Math.floor(Math.random() * array.length)];
}

Implement a function to select random elements from an array of arrays as a concatenated string:

function randomCombination(arrayOfArrays) {
  var output = ""; 
  _.each(arrayOfArrays, function(innerArray) {
    output += randomElement(innerArray);
  })
  return output
}

Now you can get a desired output by doing something like:

randomCombination(shuffle(arrayOfArrays));

or, if you want to keep arrayOfArrays intact:

randomCombination(shuffle(arrayOfArrays.slice(0)));
Community
  • 1
  • 1
dug
  • 2,275
  • 1
  • 18
  • 25
1

Instead you can use the zip function of lodash which creates an array of grouped elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements of the given arrays, and so on.

_.zip(['fred', 'barney'], [30, 40], [true, false]);
// → [['fred', 30, true], ['barney', 40, false]]
JanviM
  • 98
  • 1
  • 8