Why did targets.some not return true and prevent repeat of coordinates generated?

Why did targets.some not return true and prevent repeat of coordinates generated?
javascript
Ethan Jackson

Console output was as follows:

Targetting Pattern: Random About Target Grid Coordinates: [ 20 , 10 ] Salvo Coordinates: 21,12, 21,11, 17,8, 19,7, 21,12, <<== duplicate 20,12, 20,7, 18,12, 21,8, 22,11 <<== duplicate

Code Extract (1st approach): (using 'some' method)

function firePattern_onTargRand( col, row ){ var firePattern = 'Random About Target' ; var target = [] ; var targets = [] ; var munitionsCost = 10 ; for( i=1 ; i <= munitionsCost ; i++ ){ do { target = [ col + getRandomInteger( 0, 6 ) -3 , row + getRandomInteger( 0, 6 ) -3 ] ; } while( targets.some(element => element === target ) ) ; targets.push( target ) ; } ; console.log( "Targetting Pattern: " + `${firePattern}` + "\nGrid Coordinates: [" + ` ${col} , ${row} ` + "]\nSalvo Coordinates:\n" + targets ) ; return targets ; } ;

Code Extract (2nd approach): (direct comparison of array elements in loop)

function firePattern_onTargRand( col, row ){ var firePattern = 'Random About Target' ; var target = [] ; var targets = [] ; var munitionsCost = 10 ; var alreadyTargetted = false ; for( i=1 ; i <= munitionsCost ; i++ ){ do { target = [ col + getRandomInteger( 0, 6 ) -3 , row + getRandomInteger( 0, 6 ) -3 ] ; alreadyTargeted = false ; for( let i = 0 ; i < targets.length ; i++ ){ if( targets[i] == target ) { alreadyTargeted = true ; } ; } ; } while( alreadyTargeted === true ) ; } ; targets.push( target ) ; console.log( "Targetting Pattern: " + `${firePattern}` + "\nGrid Coordinates: [" + ` ${col} , ${row} ` + "]\nSalvo Coordinates:\n" + targets ) ; return targets ; } ;

Anyone know why I keep getting duplicates, when every pair of coordinates should be unique?

PS - I am very much a JavaScript novice.

Answer

You cannot compare objects and arrays. JS does not compare content of them but only pointers. You should compare row and col separately

function firePattern_onTargRand( col, row ){ var firePattern = 'Random About Target' ; var target = [] ; var targets = [] ; var munitionsCost = 10 ; var alreadyTargetted = false ; for( i=1 ; i <= munitionsCost ; i++ ){ do { target = [ col + getRandomInteger( 0, 6 ) -3 , row + getRandomInteger( 0, 6 ) -3 ] ; } while( targets.some(element => element.col === target.col && element.row === target.row ) ) ; targets.push( target ) ; } ; console.log( "Targetting Pattern: " + `${firePattern}` + "\nGrid Coordinates: [" + ` ${col} , ${row} ` + "]\nSalvo Coordinates:\n" + targets ) ; return targets ; } ;

To make it a little faster I propose using not array but object with keys:

function firePattern_onTargRand(col, row) { var firePattern = 'Random About Target'; var target = []; var targets = {}; var munitionsCost = 10; var alreadyTargetted = false; for (i = 1; i <= munitionsCost; i++) { let key = ''; do { target = [ col + getRandomInteger(0, 6) - 3, row + getRandomInteger(0, 6) - 3 ]; key = target.col + '_' + target.row } while (targets[key]); targets[key] = target; }; //Now remove keys targets = Object.values(targets) console.log("Targetting Pattern: " + `${firePattern}` + "\nGrid Coordinates: [" + ` ${col} , ${row} ` + "]\nSalvo Coordinates:\n" + targets); return targets; };

Related Articles