este es mi punto x=3; matriz =[4,8,7,5,6,9];
si quisiera saber si hay un valor en el arreglo igual a x, y si no lo hay, encontrar los dos valores más cercanos a la izquierda y a la derecha, en ese caso son [4,5]
Estaba pensando en encontrar para buscar si hay un valor igual y dos reduce para encontrar el más cercano más pequeño y otro reduce para encontrar el más cercano más alto, pero creo que debería haber una mejor manera
Además, necesito el índice de los resultados ya que tengo que obtener el valor en la misma posición desde otra matriz. Este es mi código:
let prevX, nextX; let prevY, nextY; let xIndex = xDatas.findIndex((xData)=>{ return xPoint == xData }) if(xIndex!=-1) return yDatas[xIndex] else{ prevX = xDatas.reduce(function(prev:number, curr:number) { return (Math.abs(curr - xPoint) < Math.abs(prev - xPoint) ?curr: prev); }); prevY = yDatas[xDatas.indexOf(prevX)]; nextX = xDatas.reduce(function(prev:number, curr:number) { return (Math.abs(curr - xPoint) > Math.abs(prev - xPoint) ? curr : prev); }); nextY = yDatas[xDatas.indexOf(nextX)];Creo que podemos mejorar esto, pero esta es una manera:
const detectClose = (x, array) => { // if has x, just return an array with x; if (array.includes(x)) { return [x]; } // if array has less or equal 2 elements, no further verification needed if (array.length <= 2) { return array; } // function to sort array elements by its absolute distance to 'x' const sort = (sortArray) => sortArray.sort((a, b) => { return Math.abs(a - x) > Math.abs(b - x) ? 1 : -1; }); // gets the numbers to the right, ordered by distance to x const higher = sort(array.filter((i) => i > x)); // gets numbers to the left, ordered by distance to x const lower = sort(array.filter((i) => i < x)); // no higher number? results will come from the left. if (higher.length === 0) { return [lower[1], lower[0]]; } // if no lower numbers, results must come from the right if (lower.length === 0) { return [higher[0], higher[1]]; } // it has numbers left or right, return the closest in each array return [lower[0], higher[0]]; };EDITAR
Puede obtener el índice después de llamar a la función
const x = 3; const array = [4,8,7,5,6,9]; const items = detectClose(x, array); const itemsIndex = items.map((i) => array.findIndex((j) => j == i));La idea en el siguiente código es construir las matrices izquierda y derecha para que las dos primeras entradas en las matrices sean las más cercanas (siendo 0 la más cercana) a la izquierda y derecha del número respectivamente. Se les permite crecer más de los dos requeridos ya que se recortan al final. Si tanto la izquierda como la derecha tienen valores, solo necesitamos el primero de cada matriz.
No estaba seguro de si solo quería el índice, así que devolví tanto el valor como el índice.
const add_maybe = (arr, val, direction, obj) => { if(arr[0] === undefined || (direction * val) > (direction * arr[0].val)) arr.unshift(obj); else if(arr[1] === undefined || (direction * val) > (direction * arr[1].val)) arr.splice(1, 0, obj); }; const find_closest = (x, arr) => { if(arr.length < 3) return arr; let left = []; let right = []; for(let index = 0; index < arr.length; index++) { let val = arr[index]; let obj = { index, val }; if(val === x) return [obj]; let lt = val < x; add_maybe(lt ? left : right, val, lt ? 1 : -1, obj); } if(!left.length) return right.slice(0, 2); if(!right.length) return left.slice(0, 2).reverse(); return [left[0], right[0]]; }; console.log(JSON.stringify( find_closest(3, [4,8,7,5,6,9]) )); console.log(JSON.stringify( find_closest(6, [4,8,7,5,9,10]) )); console.log(JSON.stringify( find_closest(11, [4,8,7,5,9,10]) )); console.log(JSON.stringify( find_closest(5, [4,8,7]) )); console.log(JSON.stringify( find_closest(-1, [6,0,9,-2,8,-7]) ));