0

Let's assume we have an array of items:

const arr1 = [22, 54, 67, 11, ...so on]

and empty one:

let arr2 = []

I can add random item with:

arr2 = [...arr2, arr1[Math.floor(Math.random()*arr1.length)]]

BUT how can I add a random item from first array to 2nd and already added should not be added?

Yes, we can keep added indexes in some tmp variable, but it doesnt seems right and I think there should be a different solution.

NOTE: array spreads because I need to add an item with some events. For example user click to button and new item will be added to 2nd array, and this array may contain already added elems

6
  • 1
    Can the original array have its entries removed as they're added to the second array? If not, could a copy be made of that original array, and the entries for the second array be removed from that? Commented Jul 6, 2018 at 13:45
  • why spreading an empty array? Commented Jul 6, 2018 at 13:45
  • 4
    Remove the items from arr1 as you add them to arr2. Use a copy of arr1 is you want to preserve the original Commented Jul 6, 2018 at 13:45
  • 2
    @NinaScholz: presumably because it's not empty after the first item has been added. Commented Jul 6, 2018 at 13:45
  • 1
    I would suggest if you want to get random values at once why not just shuffle the original array and use it according to your need. This will be the least memory taking solution. Otherwise, @MattBurland suggestion is the great suggestion. Commented Jul 6, 2018 at 13:57

7 Answers 7

1

You can create your custom logic to push the random value in arr2 so that the condition is that the numbers must be unique in arr2 and it will have maximum random numbers till the length of arr1:

const arr1 = [27, 54, 67, 11, 15, 22, 26, 58, 45, 87];
let arr2 = [];

function getRandom(){
  var randomNumber = arr1[Math.floor(Math.random()*arr1.length)];
  while(arr2.indexOf(randomNumber) !== -1 && arr2.length !== arr1.length) {
    randomNumber = arr1[Math.floor(Math.random()*arr1.length)];
  }
  arr2.push(randomNumber);
}
getRandom(); getRandom(); getRandom(); getRandom(); getRandom(); getRandom(); getRandom(); getRandom(); getRandom(); getRandom();getRandom();
console.log(arr2);

Sign up to request clarification or add additional context in comments.

2 Comments

Ain't this same answer as above answers.
@UllasHunka No. That use recursion and it has if-else block. Mine is simplified.
1

I think you are looking for something like this:

const arr1 = [22, 54, 67, 11, 23, 56, 43, 77, 34, 76, 30]

let arr2  = []


function addRandom() {

  if(new Set(arr1).size === arr2.length) return;  //prevention from infinite loop
  // if(arr1.length=== arr2.length) return;  // if arr1 doesn't contain duplicates
  let random = arr1[Math.floor(Math.random()*arr1.length)];
  if (!arr2.includes(random)) {
    arr2.push(random);
  } else {
    addRandom();
  }
}

addRandom();
console.log(arr2);

addRandom();
console.log(arr2);

addRandom();
console.log(arr2);

If you are sure that arr1 wont contain duplicates then replace (new Set(arr1).size === arr2.length) with arr1.length=== arr2.length.

6 Comments

I don't think the answer is far better then @Nicolas it could cause him the infinite loop.
@UllasHunka no it wont. See prevention from infinite loop comment
sir that part of the method is not a problem but calling the method from the method is. Let assume if the desired result returned after 10000 times of method ran. Because he is using Math.random() and random can be anything.
@UllasHunka Yes, but it won't cause an infinite loop.
How can you say it won't?
|
1

If this is ok to mutate arr1 (as Matt Burland suggested in comments), try this:

arr2 = [...arr2, ...arr1.splice(Math.floor(Math.random()*arr1.length), 1]);

splice will remove the item from arr1 and return you the item removed, ready to be added in arr2!

If you cannot change it, just make a clone before using this line!

Hoping this will help you :)

Comments

0

If compatibility is not an issue you can use array set.

var arr1 = [44, 55, 100];
var arr2 = [44, 55, 100];

var arr3 = [...new Set(arr1, arr2)];

Comments

0

Something like this should work

let arr1 = [22,43,67,11,63];
let indexes = [...arr1.keys()];
indexes = indexes.sort(() => Math.Random() - 0.5);
let arr2 = [];
arr2 = [...arr2, arr1[indexes.pop()]]

This lets you preserve the original order of your first array too.

Comments

0

You could use the include function on your second array and check if the element you are trying to add does not exists.

let randomItem = arr1[Math.floor(Math.random()*arr1.length)];
while(arra2.includes(randomItem)) {
    randomItem = arr1[Math.floor(Math.random()*arr1.length)];
}
arr2.push(randomItem);

5 Comments

I believe this is more memory taking solution loop may run infinite times to achieve the goal.
this wont work because it wont be added to new array in case random item is not matches
it will add the item if it is not already in the second array. I don't get what you are trying to do.
ok behavior -> user clicks -> new random item added, in case this item already added, script should pick another elem, which is not added yet. In your example there no item will be added in case item is already in bundle.
I've added a while loop that will pick an item at random until it found an unique one. then add it.
0

@WebArtisan, you can also try the below code.

// Function that returns a randomly selected unique list of items from another 
// array with duplicated items
function getUniqueRandomItems(arr1) {
	let arr2 = [];

	while(arr1.length) {
		// A random number in range [0, arr1.length-1]
		randomIndex = Math.floor((Math.random() * (arr1.length)) + 1) - 1; 

		// Removing 1 item from random index in range
		removedItem = arr1.splice(randomIndex, 1)[0]; 
		
		// If removedItem does not exist then add it to arr1
		if(arr2.indexOf(removedItem) < 0) {
		    arr2.push(removedItem);  
		}
	}

	return arr2 // Return the result array with unique random items
}

/************ TEST 1****************************************/
const arr1 = [22, 54, 67, 11, 54, 22, 67, 11, 88, 90, 54, 2, 3, 2, 11, 54, 0];
const arr2 = getUniqueRandomItems(arr1);
console.log(arr2); // [ 2, 22, 88, 67, 54, 11, 3, 90, 0 ]

/************ TEST 2****************************************/
const arr3 = [1, 5, 2, 5, 1, 3, 3, 6, 3, 1, 9, 8, 10, 9, 7, 4, 3, 4, 2, 1, 10];
const arr4 = getUniqueRandomItems(arr3);
console.log(arr4); // [ 1, 7, 9, 10, 5, 3, 2, 8, 4, 6 ]

Comments

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.