Así que mi caso es así, mi software que se está desarrollando en JavaScript necesita manipular valores numéricos exactos, pero a veces puede suceder que los valores estén demasiado cerca y deba discriminar.
Este es un ejemplo de caso:
0:(2) [112.02598008561951, 9.12963236661007] 1:(2) [112.02598008561952, 9.129632366610064] 2:(2) [9.751846481442218, 3.5376744911193576]En esta matriz, la posición 0 y 1 tiene valores similares pero con una ligera diferencia al final de los decimales, pero la que cuenta es la posición 0, porque los dos números están muy cerca, lo que interfiere con el proceso que sigue.
Entonces, ¿cómo hago para discriminar números cercanos y solo uso el primero de los números similares dados?
Al final, el resultado final sería una matriz como esta:
0:(2) [112.02598008561951, 9.12963236661007] 1:(2) [9.751846481442218, 3.5376744911193576]Intenté hacer un truncamiento pero necesito el número completo para trabajar.
Editar: como uno de los comentarios preguntó si los puntos pueden variar o no, en mi problema real obtengo una serie de números que ordeno normalmente obtengo como 3 puntos o, en el mejor de los casos, obtengo 2 puntos.
A veces, este problema ocurre cuando me acerco a los números y la primera capa de clasificación no funciona según lo previsto y la siguiente parte no funciona bien.
En resumen, debe considerar que siempre es como 3 posiciones de coordenadas.
En resumen, su opción más fácil es redondear a un número fijo de lugares decimales. Esto se debe a que los flotadores en JS (y en informática en general) pueden ser complicados. Por ejemplo, esto debería hacer que quieras tirar tu computadora:
var x = 0.1 * 0.2; //-> 0.020000000000000004Hay diferentes casos de uso para necesitar una precisión superexacta (por ejemplo, cuando se trata de dinero, la trayectoria de un satélite, etc.), pero la mayoría de los casos de uso solo necesitan una precisión "suficientemente buena". En su caso, es mejor redondear todos sus números a una longitud decimal fija para que no encuentre imprecisiones de bajo nivel.
var ACCURACY = 100000000; var round= (num) => Math.round(num * ACCURACY) / ACCURACY; var x = round(0.1 * 0.2); //-> 0.2Si confía en los números que tiene y solo necesita filtrar un par que está cerca de otro par, deberá escribir una pequeña función para aplicar su heurística.
var areClose = (x, y) => Math.abs(x - y) < 0.0000000001; var filterPoints = (arr) => { return arr.filter(([x, y], i) => { for(var n = i - 1; n >= 0; n--) { if (areClose(x, arr[n][0]) && areClose(y, arr[n][1])) { return false; } } return true; }); } filterPoints([ [112.02598008561951, 9.12963236661007], [112.02598008561952, 9.129632366610064], [9.751846481442218, 3.5376744911193576], ]); // [ // [112.02598008561951, 9.12963236661007], // [9.751846481442218, 3.5376744911193576]] // ]Nota: esto mantendrá el "primer" conjunto de valores. Si desea mantener el "último" conjunto, puede voltear el bucle interno para arrastrarse hacia arriba:
for(var n = i + 1; n < arr.length; n++) { ...
Veamos si entendí correctamente, tiene esta matriz con puntos de vértice, generalmente es solo una matriz bidimensional de 2 elementos, pero a veces puede recibir una matriz de puntos de vértice adicional, con un valor ligeramente diferente (diferencia de 1 * 10 ^ -14) y desea descartar los valores adicionales más altos.
Se me ocurrió algo como esto:
const arr = [ [112.02598008561951, 9.12963236661007], [112.02598008561952, 9.129632366610064], [9.751846481442218, 3.5376744911193576], ]; for (let i = 0; i < arr.length-1; i++) { const diff = Math.abs(arr[i][0] - arr[i + 1][0]) if (diff <= 0.00000000000002) arr.splice(i + 1, 1); } console.log("NEW ARR", arr)Esto solo verifica el primer elemento de la matriz, ya que si entendí correctamente, automáticamente significa que incluso el segundo elemento difiere en una cantidad similar. Estoy usando un umbral (2 * 10-14) ya que 1 no es suficiente, no estoy seguro de si se debe a problemas de JS con precisión flotante.
Podría ordenar y reducir
let arr = [ [112.02598008561952, 9.129632366610064], [112.02598008561951, 9.12963236661007], [9.751846481442218, 3.5376744911193576] ] arr.sort((a,b) => a[0]-b[0]); // swap a and b for descending const precision = 0.00000000000002; arr = arr.reduce((acc,cur,i) => { if (i===0) { acc.push(cur); return acc} const diff = Math.abs(acc[acc.length-1][0]-cur[0]) if (diff > precision) acc.push(cur) return acc },[]) console.log(arr)