d3.scan()中的比较器如何工作?

时间:2019-02-01 04:00:01

标签: javascript d3.js

我正在读取d3.scan()的docs

  

对指定的可迭代对象执行线性扫描,并返回索引   根据指定比较器的最小元素的大小。如果   给定的iterable不包含可比较的元素(即比较器   将每个元素与其自身进行比较时返回NaN),返回未定义。   如果未指定比较器,则默认为升序。例如:

const array = [{foo: 42}, {foo: 91}];
d3.scan(array, (a, b) => a.foo - b.foo); // 0
d3.scan(array, (a, b) => b.foo - a.foo); // 1
  

此功能类似于min,不同之处在于它允许使用   比较器而不是访问器,它返回索引而不是   访问的值。另请参阅等分。

第一个d3.scan()命令说“对于称为数组的对象,检查42岁的a.foo是否是最大值” ,第二个d3.scan()命令说< em>“对于名为array的对象,检查b.foo(91)是否是最大值” ,然后0/1是TRUE / FALSE响应。

我可以在更大的数组上使用它吗?

理解d3.scan()命令是正确的方法吗?

1 个答案:

答案 0 :(得分:4)

不,在您说“然后0/1是TRUE / FALSE响应” 时,这里对d3.scan的工作方式存在误解。

01的值不是truefalse只是它们的索引根据您的比较器,数组内的元素。您复制的那段有它:

  

对指定的可迭代对象执行线性扫描,并根据指定的比较器返回最小元素的 index 。 (强调我的)

此外,ab并不是示例数组中的第一和第二个元素(这会产生误导,因为示例数组只有2个元素):如果您查看{{3} } ...

for (const value of values) {
    ++index;
    if (minIndex === undefined
        ? compare(value, value) === 0
        : compare(value, min) < 0) {
      min = value;
      minIndex = index;
    }
}

...您将看到它们只是for...of循环中的当前元素,也是通过比较器测试的最后一个元素。

让我们在演示中看到它。假设此数组:

 const array = [{foo: 42}, {foo: 91}, {foo: 32}, {foo: 256}, {foo: 17}, {foo: 8}];

如您所见,最高的foo值是第4个元素(索引3)。检查控制台:

const array = [{
  foo: 42
}, {
  foo: 91
}, {
  foo: 32
}, {
  foo: 256
}, {
  foo: 17
}, {
  foo: 8
}];

const index = d3.scan(array, (a, b) => b.foo - a.foo);
console.log(index)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

同样,最小的foo值是最后一个元素(索引5)。再次检查控制台:

const array = [{
  foo: 42
}, {
  foo: 91
}, {
  foo: 32
}, {
  foo: 256
}, {
  foo: 17
}, {
  foo: 8
}];

const index = d3.scan(array, (a, b) => a.foo - b.foo);
console.log(index)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

话虽如此,这回答了您的第一个问题(“我可以将它用于更大的阵列吗?” ):是的,当然,这正是d3.scan的目的...我可以只需查看一下即可快速比较给定属性的两个对象的数组,我不需要d3.scan,但是对于1000个元素的数组我无法做到这一点。