Home > Net >  Pick random objects from an array with a specific property which is unique
Pick random objects from an array with a specific property which is unique

Time:12-09

I'm looking for a method to pick random objects from an array of objects where a specific property has a unique value.

Example:

const array = [
  {
    name:'foo',
    message: 'hello'
  },
  {
    name:'foo',
    message: 'world'
  },
  {
    name:'bar',
    message: 'hello'
  },
  {
    name:'bar',
    message: 'world'
  },
]

function theMagicMethod(elementsCount, specificUniqueProperty){
// ...
};

console.log(theMagicMethod(2, name));

// Expected output: [{name:'foo', message:'hello'},{name:'bar', message:'hello'}]
// or [{name:'foo', message:'hello'},{name:'bar', message:'world'}]
// etc...

// BUT NEVER WANT: [{name:'foo', message:'hello'},{name:'foo', message:'world'}]

I've tried to use do ... while or while ... but it always crash when I conditionally add an element to my result array.:


let items = [];
do{
  let item = array[Math.floor(Math.random()*array.length)];

  let found = false;
  for(var i = 0; i < vendors.length; i  ) {
      if (vendors[i].Name == 'Magenic') {
          found = true;
          break;
      }
  }

  if(!found){
    items.push(item)
  }

} while (items.length < 3)

CodePudding user response:

Shuffle the objects, use a set to filter unique values, return the first N...

// fy shuffle, thanks to https://stackoverflow.com/a/2450976/294949
function shuffle(array) {
  let currentIndex = array.length,  randomIndex;
  while (currentIndex != 0) {
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex--;
    [array[currentIndex], array[randomIndex]] = [
      array[randomIndex], array[currentIndex]];
  }
  return array;
}

function theMagicMethod(elementsCount, specificUniqueProperty) {
  let shuffled = shuffle(array.slice());
  let uniqueValues = new Set()
  let unique = shuffled.filter(el => {
    const value = el[specificUniqueProperty];
    const keep = !uniqueValues.has(value)
    uniqueValues.add(value);
    return keep;
  })
  return unique.slice(0, elementsCount);
}
  • Related