平分对象数组:不是所有对象都被枚举了吗?
Bisecting an array of objects: are not all of them enumerated?
这是我的平分线:
var bisectDate = d3.bisector(function(d: any) {
console.log('d date ', d.date);
return d.date;
}).left;
我有一组日期(总共 78 个),但在我的平分线上它只重复记录 5 个,如下所示?
timesDataPath (78) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, ...]
App.tsx:122 d date Mon Aug 12 2019 12:45:00 GMT+0800 (Singapore Standard Time)
App.tsx:122 d date Mon Aug 12 2019 11:05:00 GMT+0800 (Singapore Standard Time)
App.tsx:122 d date Mon Aug 12 2019 10:15:00 GMT+0800 (Singapore Standard Time)
App.tsx:122 d date Mon Aug 12 2019 09:50:00 GMT+0800 (Singapore Standard Time)
App.tsx:122 d date Mon Aug 12 2019 09:40:00 GMT+0800 (Singapore Standard Time)
App.tsx:122 d date Mon Aug 12 2019 09:35:00 GMT+0800 (Singapore Standard Time)
怎么会这样?我在数组中的对象是这样的:
{
1. open: "25891.8496"
2. high: "25896.8809"
3. low: "25890.6797"
4. close: "25893.1504"
5. volume: "3205446"
date: Mon Aug 12 2019 16:00:00 GMT+0800 (Singapore Standard Time) {}
}
我是这样使用它的:
.on('mousemove', function() {
var mouse = d3.mouse(this);
var mouseDate = xScale.invert(mouse[0]);
var i = bisectDate(timesDataPath, mouseDate);
timesDataPath
是我用于 x 轴和 y 轴的,我对图表没有任何问题,只是将这部分作为指针不起作用。
这是预期的行为。
如果您查看 d3.bisector
的 source code,您会发现它并没有按照您的想法迭代整个数组。看看这里:
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) > 0) hi = mid;
else lo = mid + 1;
}
有趣的部分在于:var mid = lo + hi >>> 1;
。这个按位(名为 zero-fill right shift)所做的是计算数组的 中点 。
在你的例子中,数组有 78 个元素。因此:
console.log(0 + 78 >>> 1)
并且它不断获取剩余部分的中点,一次又一次,直到找到元素。看看这里:
let lo = 0,
hi = 78;
while (lo < hi) {
let mid = lo + hi >>> 1;
console.log(mid)
lo = mid + 1;
}
对于 78 个元素的数组,它执行了 6 次(不是你提到的 5 次),这就是为什么你看到 console.log
只工作了 6 次。
看看这个演示,一个包含 78 个元素的数组,console.log
工作了 7 次:
const data = d3.range(78);
const bisect = d3.bisector(function(d) {
console.log(d);
return d;
}).left;
bisect(data, 5);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
现在让我们将数组增加到 1000 个元素。 console.log
工作 10 次:
const data = d3.range(1000);
const bisect = d3.bisector(function(d) {
console.log(d);
return d;
}).left;
bisect(data, 5);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
这是我的平分线:
var bisectDate = d3.bisector(function(d: any) {
console.log('d date ', d.date);
return d.date;
}).left;
我有一组日期(总共 78 个),但在我的平分线上它只重复记录 5 个,如下所示?
timesDataPath (78) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, ...]
App.tsx:122 d date Mon Aug 12 2019 12:45:00 GMT+0800 (Singapore Standard Time)
App.tsx:122 d date Mon Aug 12 2019 11:05:00 GMT+0800 (Singapore Standard Time)
App.tsx:122 d date Mon Aug 12 2019 10:15:00 GMT+0800 (Singapore Standard Time)
App.tsx:122 d date Mon Aug 12 2019 09:50:00 GMT+0800 (Singapore Standard Time)
App.tsx:122 d date Mon Aug 12 2019 09:40:00 GMT+0800 (Singapore Standard Time)
App.tsx:122 d date Mon Aug 12 2019 09:35:00 GMT+0800 (Singapore Standard Time)
怎么会这样?我在数组中的对象是这样的:
{
1. open: "25891.8496"
2. high: "25896.8809"
3. low: "25890.6797"
4. close: "25893.1504"
5. volume: "3205446"
date: Mon Aug 12 2019 16:00:00 GMT+0800 (Singapore Standard Time) {}
}
我是这样使用它的:
.on('mousemove', function() {
var mouse = d3.mouse(this);
var mouseDate = xScale.invert(mouse[0]);
var i = bisectDate(timesDataPath, mouseDate);
timesDataPath
是我用于 x 轴和 y 轴的,我对图表没有任何问题,只是将这部分作为指针不起作用。
这是预期的行为。
如果您查看 d3.bisector
的 source code,您会发现它并没有按照您的想法迭代整个数组。看看这里:
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) > 0) hi = mid;
else lo = mid + 1;
}
有趣的部分在于:var mid = lo + hi >>> 1;
。这个按位(名为 zero-fill right shift)所做的是计算数组的 中点 。
在你的例子中,数组有 78 个元素。因此:
console.log(0 + 78 >>> 1)
并且它不断获取剩余部分的中点,一次又一次,直到找到元素。看看这里:
let lo = 0,
hi = 78;
while (lo < hi) {
let mid = lo + hi >>> 1;
console.log(mid)
lo = mid + 1;
}
对于 78 个元素的数组,它执行了 6 次(不是你提到的 5 次),这就是为什么你看到 console.log
只工作了 6 次。
看看这个演示,一个包含 78 个元素的数组,console.log
工作了 7 次:
const data = d3.range(78);
const bisect = d3.bisector(function(d) {
console.log(d);
return d;
}).left;
bisect(data, 5);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
现在让我们将数组增加到 1000 个元素。 console.log
工作 10 次:
const data = d3.range(1000);
const bisect = d3.bisector(function(d) {
console.log(d);
return d;
}).left;
bisect(data, 5);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>