我的React组件状态中有一个对象,如下所示:
const elementPositions = {
"0": 180.2,
"1": 350.8666666666667,
"2": 521.5333333333333,
"3": 692.2,
"4": 862.8666666666667,
"5": 1033.5333333333333,
"6": 1204.2
}
我有滚动侦听器,它返回一个滚动位置值,让我们在这个例子中说const scrollY = 466
。
我需要创建一个返回滚动位置的相应索引的函数 - 即466
将返回1,因为它大于350
但小于521
。实现这一目标的最佳方法是什么?我正在思考这方面的事情,但我不确定它是最好的方法:
const values = Object.values(elementPositions)
values.push(scrollY)
values.sort((a, b) => {return a-b})
const newIndex = values.indexOf(scrollY) - 1
答案 0 :(得分:2)
假设elementPositions
是一个数组:
[180.2, 350.866, ...]
这将返回O(n)
中的值(优于排序):
// Get all values smaller than current scrollY
positions = elementPositions.filter(e => e <= scrollY);
// The last element will be the one closest
value = positions.length ? positions[positions.length - 1] : elementPositions[0];
然后,您可以根据需要使用.indexOf
获取索引。
这绝不是有效的,你不应该在每个滚动事件上都这样做。
最有效的方法可能是进行O(log n)
的二进制搜索:
function rec_search(array, value, left, right) {
if (right - left == 1) return left;
var middle = Math.floor((left + right) / 2),
middleValue = array[middle];
if (value < middleValue) return rec_search(array, value, left, middle);
else return rec_search(array, value, middle, right);
}
function search(array, value) {
if (array.length == 0) return -1;
if (value < array[0]) return -1;
if (value > array[array.length - 1]) return array.length - 1;
return rec_search(array, value, 0, array.length - 1);
}
var positions = [1, 2, 4, 8, 16, 32]; // sorted array
console.log(search(positions, 7));
&#13;
如果您知道生成数字的函数,也可以用代数方式计算索引。
答案 1 :(得分:2)
你的数字似乎是大约170的增量,所以你应该能够在恒定时间内进行算术运算(没有排序,循环等)。
const elementPositions = {
"0": 180.2,
"1": 350.8666666666667,
"2": 521.5333333333333,
"3": 692.2,
"4": 862.8666666666667,
"5": 1033.5333333333333,
"6": 1204.2
};
function getPos(x) {
return elementPositions[Math.floor((x-180.2) / 170.66666666666)] || 0;
}
// test
for (const n of [0,10,180,181,350,351,466,521,522,692,693,862,863,1033,1034,1204,1205]) {
console.log(n, getPos(n));
}
&#13;