首页 > 解决方案 > 如果第二个参数是数字,则 bisectLeft 函数不起作用

问题描述

在我正在实现的一个小例程中,我使用了 d3.js 的 bisectLeft 函数。我正在使用最新版本(v5.9.2)。如果我这样做,一切都很好:

var dataArray = [10, 20, 50, 40, 30, 600];
d3.bisectLeft(dataArray, 30); //2

但如果我这样做,不:

var dataArray = [[10,1],[20,2],[50,5],[40,4],[30,3],[600,60]];
d3.bisectLeft(dataArray, 30); //0 Bad!

但是,这很好用:

var dataArray = [[10,1],[20,2],[50,5],[40,4],[30,3],[600,60]];
d3.bisectLeft(dataArray, '30'); //2 Good!

这是设计使然吗?我已经查看了源代码和文档,但我不明白为什么会这样。一旦知道这个问题很容易在我的代码中修复,但我仍然有疑问,我不知道我是否遗漏了什么。

标签: javascriptd3.js

解决方案


这里的问题是你有一个数组数组。在这种情况下,您必须使用d3.bisector适当的访问器函数,以便 D3 可以知道要比较的值是什么。根据文档,这种方法...

使用指定的访问器或比较器函数返回一个新的平分线。此方法可用于平分对象数组,而不是仅限于简单的基元数组。(强调我的)

在您的情况下,这将是:

const bisector = d3.bisector(function(d) { return d[0]; }).left;

如您所见,这将通过选择每个内部数组中的第一个数字来有效地将数组数组转换为单个数字数组,就像您问题中的第一个片段一样。

另外,请注意需要对数组进行排序这一事实(否则人们将永远无法理解您的问题中为什么2好”!)。

这是演示:

var dataArray = [
  [10, 1],
  [20, 2],
  [50, 5],
  [40, 4],
  [30, 3],
  [600, 60]
];
dataArray = dataArray.sort(function(a, b) {
  return a[0] - b[0];
});
const bisector = d3.bisector(function(d) {
  return d[0];
}).left;
const result = bisector(dataArray, 30);

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>


推荐阅读