假设我有一个对象数组:
var array = [
{ id: 1, pt: 0 },
{ id: 2, pt: 12 },
{ id: 3, pt: 7 },
{ id: 4, pt: 45 },
{ id: 5, pt: 123 },
];
我想遍历数组(使用array.forEach
或array.map
之类的东西,并将每个项目中的pt
属性与数组中其他项目的属性进行比较。我的目标是,对于每个项目,找到价值最接近该项目的其他 3 个项目pt
价值。例如。对于id: 1
,值中最接近的项目是 2、3 和 4。对于id: 3
,它将是 1、2 和 4,依此类推......我怎样才能做到这一点?
您将过滤结果映射到排除枢轴元素并按绝对增量排序并获取所需的数量作为结果。
function closest(n, { id, pt }) {
return array
.filter(o => o.id !== id)
.sort((a, b) => Math.abs(a.pt - pt) - Math.abs(b.pt - pt))
.slice(0, n);
}
var array = [{ id: 1, pt: 0 }, { id: 2, pt: 12 }, { id: 3, pt: 7 }, { id: 4, pt: 45 }, { id: 5, pt: 123 }],
result = array.map(o => Object.assign({}, o, { closest: closest(3, o) }));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
首先让我们对数组进行排序:
array.sort((a, b) => a.pt - b.pt);
现在,最接近的元素位于元素之前或之后的某个位置。 为了得到它们,可以前进和后退:
function getClosest(pos, n) {
let lower = pos - 1, upper = pos + 1;
const distance = i => Math.abs(array[pos].pt - array[i].pt);
const result = [];
while(result.length < n) {
if(lower >= 0 && distance(lower) < distance(upper)) {
result.push(array[lower--]);
} else if(upper < array.length) {
result.push(array[upper++]);
} else break;
}
return result;
}
现在要获取第一个元素的 5 个最接近的祖先:
getClosest(0, 5)