1

I want to have an object made of arrays containing integers as indicators used by another method. Each array of integers have to be different, but my function has to randomly create them and while adding a new array make sure that it doesn't exist already, but at the same time a specific amount of arrays have to be added.

Lets say I want an object that look like this:

arr = { 
  0: [0,0],
  1: [0,1],
  2: [1,1],
  3: [1,0]
}

The above object can be in different order of course, depending on the random aspect of below Math.random. That's the code I have:

let arrayOfPositions = [];
let i = 0;
let position = [];

do {
  let randX = Math.round(Math.random());
  let randY = Math.round(Math.random());
  position = [randX, randY];
  arrayOfPositions[i] = position;
  i++;
}

while (arrayOfPositions.length < 4 );

There's something missing in my while condtition to check if the position already exist in the arrayOfPositions. I tried indexOf and lastIndexOf but it then always stopped after first array added.

Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
Abbys
  • 137
  • 10

2 Answers2

1

The problem is that you're using indexOf and lastIndexOf while searching for the index of an Object (an Array in this case) and both of them only work for primitives.

You can either stringify the values (1) or check for the inner Array values for equality (2).

(1) is a bit tricky and slow, because you'd have to stringify both the original array value (arrayOfPositions), the new position you're trying to add and then you can use indexOf and its derivatives. So I'm going to skip that one.

For (2) I'd change the code a little bit and assume you can use ES6 Array.find as you're using let:

let positions = []
do {
  const position = createUniquePos(positions)
  positions.push(position)
}
while (positions.length < 4)

function createUniquePos(positions) {
  const x = Math.round(Math.random())
  const y = Math.round(Math.random())
  // here we check if that pair already exists in the array
  return positions.find( pos => pos[0] === x && pos[1] === y )
    // if it does exist, then we do another attempt with recursion
    ? createUniquePos(positions)
    // if it doesn't, then we return the unique position
    : [x, y]
}
GMaiolo
  • 4,207
  • 1
  • 21
  • 37
  • Works perfectly. Thank you for the clear explanation of where the problem was. Appreciated. – Abbys Feb 19 '18 at 17:01
  • Just one question though, how can I expand on this if the arrays can change from two values to more? Like [0,0] at the start and [0,0,0,0,0,0,0] later on. – Abbys Feb 19 '18 at 17:19
  • Not sure if I'm following, could you provide a full resulting array? – GMaiolo Feb 19 '18 at 17:21
-1
const positionSet = new Set();
while(positionSet.size < 4){
  const randX = Math.round(Math.random());
  const randY = Math.round(Math.random());
  const position = [randX, randY];
  positionSet.add(position);
}

A set is unique, so if you add the same value, then it will just be ignored.

If you want to use array function like map, filter or reduce, then you can do Array.from(positionSet); or if you don't have ES7, you can write Array.prototype.slice.call(positionSet);

Pavlo
  • 1,157
  • 7
  • 13
  • You are right, they worked differently in TypeScript, but it works to check for `has` though with objects – Pavlo Feb 19 '18 at 16:30