1

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)
2
  • What approach have you tried thus far? Can you put it in your question? Commented Dec 8, 2021 at 23:31
  • I've just add my approach sorry Commented Dec 8, 2021 at 23:40

1 Answer 1

1

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);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Oh damn thank you wery I was far from this approach
Dang @danh!! I just threw together an identical answer only to see you beat me by 5 minutes. Well done :)
Thank you too @Kinglish for your time!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.