0

I'd be grateful if someone can explain what I'm doing wrong here. I compare two arrays of geographic coordinates, successfully find the common elements and then try to get the indexes for the first hit. Only arrB works as expected. Although the key is quite clearly at arrA[1], no match is found. I've included loads of logging because I don't quite believe what I'm seeing.

function arrayIntersect(a, b) {
/* credit  https://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript */
 var aa = {};
  a.forEach(function(v) { aa[v]=1; });
  return b.filter(function(v) { return v in aa; });
}

const arrA = [[53.88,-2.96],[53.7,-2.45],[53.79,-2.52],[53.66,-2.61],[53.98,-2.34],[53.92,-2.36],[53.89,-2.95],[53.9,-2.94],[53.88,-2.4],[53.89,-2.81],[53.93,-2.77],[53.87,-2.13],[53.9,-2.54],[53.6,-2.91],[54.01,-2.83],[53.83,-2.44],[53.6,-2.88],[54.02,-2.76],[53.99,-2.8],[54.15,-2.79],[53.85,-2.13],[53.62,-2.96],[54,-2.84],[53.66,-2.75],[53.91,-2.27],[53.86,-2.62],[53.51,-2.13],[53.82,-2.3]]
const arrB = [[53.82,-2.9],[53.95,-2.73],[53.62,-2.73],[54.11,-2.81],[54.18,-2.84],[53.53,-2.09],[53.83,-2.98],[53.87,-2.42],[53.82,-2.66],[53.87,-2.41],[53.88,-2.98],[53.96,-2.75],[53.53,-2.02],[53.7,-2.45],[54.06,-2.87],[53.94,-2.34],[53.7,-2.87],[53.61,-2.89],[54.18,-2.84],[54.12,-2.8],[53.86,-2.82],[53.9,-2.53],[53.91,-2.86],[53.81,-2.26],[53.8,-2.51],[53.79,-2.98],[53.79,-3],[53.74,-2.92],[54.11,-2.8],[53.96,-2.49],[53.89,-2.44],[53.87,-2.12],[53.93,-2.77],[53.93,-2.78],[53.86,-2.86],[54.14,-2.46],[54.08,-2.78],[54.07,-2.75],[53.94,-2.86],[53.78,-3],[54.02,-2.89],[53.86,-2.26],[53.68,-2.79],[53.66,-2.75],[53.66,-2.88],[53.78,-2.79],[53.66,-2.31],[53.67,-2.3],[53.6,-2.08],[53.63,-2.09],[54.16,-2.83],[53.62,-2.96],[53.84,-2.15]]

console.log(arrA.length + '  ' + Array.isArray(arrA))
console.log(arrB.length + '  ' + Array.isArray(arrB))
console.log(arrA[0].length + '  ' + Array.isArray(arrA[0]))     // sample entries
console.log(arrB[0].length + '  ' + Array.isArray(arrB[0]))

res = arrayIntersect(arrA, arrB)      ; console.log('res  ' + res + '  ' + Array.isArray(res))

let key = res[0]                      ; console.log('key  ' + key + '  ' + Array.isArray(key))

let idxA = arrA.indexOf(key)          ; console.log('idxA ' + idxA)
let idxB = arrB.indexOf(key)          ; console.log('idxB ' + idxB)

Results

Server started at http://localhost:8080
28  true
53  true
2  true
2  true
res  53.7,-2.45,53.93,-2.77,53.66,-2.75,53.62,-2.96  true
key  53.7,-2.45  true
idxA -1
idxB 13
perplexed
  • 5
  • 2
  • Some things that may surprise you: `[[1]].indexOf([1])`, `[1] === [1]`, You may want to `.findIndex` and [compare the arrays](https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript). – Wyck Jun 06 '22 at 16:33

1 Answers1

0

When you use arrays with objects in it the indexOf function compares then the object reference and not the object itself to get the index value. And remember, in your case you have arrays in arrays but in javascript also arrays are objects so this aplies as well in your case.

Then your arrayIntersect function filters arrB, therefor the originale objects from arrB are stored then in the res array which then only can be used to get back the index in the arrB.

One approach could be to just use find for arrA to get the index and just stringify the objects while comparing:

function arrayIntersect(a, b) {
/* credit  https://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript */
    var aa = {};
    a.forEach(function(v) { aa[v]=1; });
    return b.filter(function(v) { return v in aa; });
}

const arrA = [[53.88,-2.96],[53.7,-2.45],[53.79,-2.52],[53.66,-2.61],[53.98,-2.34],[53.92,-2.36],[53.89,-2.95],[53.9,-2.94],[53.88,-2.4],[53.89,-2.81],[53.93,-2.77],[53.87,-2.13],[53.9,-2.54],[53.6,-2.91],[54.01,-2.83],[53.83,-2.44],[53.6,-2.88],[54.02,-2.76],[53.99,-2.8],[54.15,-2.79],[53.85,-2.13],[53.62,-2.96],[54,-2.84],[53.66,-2.75],[53.91,-2.27],[53.86,-2.62],[53.51,-2.13],[53.82,-2.3]]
const arrB = [[53.82,-2.9],[53.95,-2.73],[53.62,-2.73],[54.11,-2.81],[54.18,-2.84],[53.53,-2.09],[53.83,-2.98],[53.87,-2.42],[53.82,-2.66],[53.87,-2.41],[53.88,-2.98],[53.96,-2.75],[53.53,-2.02],[53.7,-2.45],[54.06,-2.87],[53.94,-2.34],[53.7,-2.87],[53.61,-2.89],[54.18,-2.84],[54.12,-2.8],[53.86,-2.82],[53.9,-2.53],[53.91,-2.86],[53.81,-2.26],[53.8,-2.51],[53.79,-2.98],[53.79,-3],[53.74,-2.92],[54.11,-2.8],[53.96,-2.49],[53.89,-2.44],[53.87,-2.12],[53.93,-2.77],[53.93,-2.78],[53.86,-2.86],[54.14,-2.46],[54.08,-2.78],[54.07,-2.75],[53.94,-2.86],[53.78,-3],[54.02,-2.89],[53.86,-2.26],[53.68,-2.79],[53.66,-2.75],[53.66,-2.88],[53.78,-2.79],[53.66,-2.31],[53.67,-2.3],[53.6,-2.08],[53.63,-2.09],[54.16,-2.83],[53.62,-2.96],[53.84,-2.15]]

console.log(arrA.length + '  ' + Array.isArray(arrA))
console.log(arrB.length + '  ' + Array.isArray(arrB))
console.log(arrA[0].length + '  ' + Array.isArray(arrA[0]))     // sample entries
console.log(arrB[0].length + '  ' + Array.isArray(arrB[0]))

res = arrayIntersect(arrA, arrB)      ; console.log('res  ' + res + '  ' + Array.isArray(res))

let key = res[0]                      ; console.log('key  ' + key + '  ' + Array.isArray(key))

let idxA = arrA.indexOf(arrA.find(el=>JSON.stringify(el)===JSON.stringify(key)))         ; console.log('idxA ' + idxA)
let idxB = arrB.indexOf(key)          ; console.log('idxB ' + idxB)
DiniFarb
  • 206
  • 2
  • 6
  • Thankyou for your explanation, which has shaken my fundamental understanding of the logical nature of computers. Calling `arrayIntersect(arrA, arrB)` or `arrayIntersect(arrB, arrA)` will produce the same four elements for the 'res' array, but different results for `idxA` and `idxB`. Writing out `const res = ` by hand gives a third result. All three of them apparently wrong. That's completely unexpected, unpredictable and baffling. I'll have to learn to live with it though! Thanks again. – perplexed Jun 06 '22 at 20:17