0

I have an array of objects with 11 properties and I want to shuffle the properties appearing in the array in a random way.

To be clear, the order of the array objects will be the same. I want to randomize the properties order inside the object and keep this order for every object.

Here is a sample of my Array:

I tried looking for any other solution to similar problems but most of them were rearanging the object whereas I need to randomize the properties

var list = [
{
    "ID": 0,
    "Name": "Mark",
    "Address": "2323 st",
    "Phone": 511 232 2000,
    "Score": 345
},
{
    "ID": 1,
    "Name": "Catrina",
    "Address": "2323 st",
    "Phone": 511 232 2100,
    "Score": 3452
} //and 1000 more objects...

And this is what I am looking for (the order should be rearranged when clicking a button)

var list2 = [
{
    "Score": 345
    "Name": "Mark",
    "Address": "2323 st",
    "ID": 0,
    "Phone": 511 232 2000, 
},
{
    "Score": 3452
    "Name": "Catrina",
    "Address": "2323 st",
    "ID": 1,
    "Phone": 511 232 2100,  
} //and 1000 more objects...

I want to get an output of list2 with the same data but in a random property order. The randomize function would be called whenever someone clicks a button, this I'll be able to do once I find a way to have a function the does what I want.

  • You have a well-defined problem statement, that's good - now could you post the code you've written that isn't working properly so we can see what's going wrong? (SO isn't here to write your whole script for you) – CertainPerformance Jan 05 '19 at 01:42
  • just so i understand - the order of the properties per object is the same for all objects in the array in list2 - or is each objects properties randomized individually? – Dan Jan 05 '19 at 01:52
  • I have tried many things but didn't stick to a certain solution so I didn't post code. I'll keep working on something and post it as it gets cleaner. – user10840968 Jan 05 '19 at 01:55
  • Yes the order of properties will be the same for every object in list2 – user10840968 Jan 05 '19 at 01:55

3 Answers3

1

If you are talking about randomly shuffling your array, below is how to do so:

function shuffle(array) {

  var currentIndex = array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}

Answer taken from here

  • I tried the code but can't seem to make it work. Isn't this for a simple array whereas I have an array with multiple properties? I might be wrong as I am pretty new to js. – user10840968 Jan 05 '19 at 02:20
  • OP is *not* trying to shuffle his array. ES6+ *does indeed* guarantee object property order. – CertainPerformance Jan 05 '19 at 04:33
0

Whenever you create a new object, the order in which you declare its properties is the order in which they appear when printed to the console or in string format via JSON.stringify().

var list = [
{
    "ID": 0,
    "Name": "Mark",
    "Address": "2323 st",
    "Phone": "511 232 2000",
    "Score": 345
},
{
    "ID": 1,
    "Name": "Catrina",
    "Address": "2323 st",
    "Phone": "511 232 2100",
    "Score": 3452
}]

function remap(d) {
    const {ID, Name, Address, Phone, Score} = d; 
    return {Score, Name, Address, ID, Phone}
}
console.log(list.map(remap))

And, presuming that the key order should be the same for each item in a given list, one approach is to enclose the code managing the randomisation inside a function working as closure. Going for functional constructs as it makes the code more compact.

var list = [{
    "ID": 0,
    "Name": "Mark",
    "Address": "2323 st",
    "Phone": "511 232 2000",
    "Score": 345
  },
  {
    "ID": 1,
    "Name": "Catrina",
    "Address": "2323 st",
    "Phone": "511 232 2100",
    "Score": 3452
  }
]


function randomizePropertyOrder() {
  // If we want the property order to remain the same throughout the list
  // we must declare it inside some closure
  let propsOrder;

  // quick way to randomize any list of items. 
  function randomizeList(list) {
    return list
             .map((k, i) => { return { k, i: Math.random(); } })
             .sort((a, b) => { return a.i - b.i; })
             .map((d) => { return d.k; })
  }

  return (d) => {
    // let's compute a random property order once and only once
    if (propsOrder === undefined) { propsOrder = randomizeList(Object.keys(d)) }
    return propsOrder.reduce((acc, k) => {
      acc[k] = d[k];
      return acc;
    }, {})

  }
}
const remap = randomizePropertyOrder()
console.log(list.map(remap))
widged
  • 2,749
  • 21
  • 25
  • It should be completely random but I could also make it work with about 5 return cases with random number generator with your solution. I tested it and it works like a charm. I might use this solution. Thank you – user10840968 Jan 05 '19 at 02:15
  • @user10840968 I added a quick way to shuffle the property order in some random way, with the property order remaining the same for all items in the list. I coded it so that you can apply a same (randomized) order onto different lists by reusing the same remap function. – widged Jan 05 '19 at 02:29
0

A bit late to the party.

How about using Durstenfeld shuffle, since you want completely random. This is computer-optimized since your list could be long and you do not want the main thread to block/slow down.

var list = [
{
    "ID": 0,
    "Name": "Mark",
    "Address": "2323 st",
    "Phone": 5112322000,
    "Score": 345
},
{
    "ID": 1,
    "Name": "Catrina",
    "Address": "2323 st",
    "Phone": 5112322100,
    "Score": 3452
}
];

var list2 = list.slice();//making replica
randomizeList(list2);
console.log(list2);
console.log(list);


function randomizeList(list2) {
    for (var i = list2.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = list2[i];
        list2[i] = list2[j];
        list2[j] = temp;
    }
}
YetAnotherBot
  • 1,937
  • 2
  • 25
  • 32