我有一个D3程序正在构建一个折线图,其中有两条线,我想确定线交叉处的坐标。 D3有这个功能吗?数组通常具有不同的长度并且是动态生成的,但是总是有一个值,两个值在相同的索引处相等。
EG
var line1 = [0,1,2,3,4];
var line2 = [4,3,2,1,0];
在这种情况下,答案=索引2。如果没有D3功能,那么使用ES6及以上的最佳方法是什么?
D3有一个非常未知的方法,名为d3.zip
,我们可以使用它来合并数组并查找所有元素相等的任何内部数组:
var line1 = [0, 1, 2, 3, 4];
var line2 = [4, 3, 2, 1, 0];
var zip = d3.zip(line1, line2).reduce(function(a, c, i) {
if (c[0] === c[1]) a.push(i);
return a;
}, []);
console.log(zip)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
关于d3.zip
的好处是它可以与几个数组一起使用,并且还保持较短数组的长度。因此,在更复杂的情况下(指数6和9中的值相等):
var line1 = [0, 1, 2, 3, 9, 9, 1, 4, 7, 6, 5, 4];
var line2 = [4, 3, 2, 1, 0, 8, 1, 2, 3, 6, 1];
var line3 = [9, 9, 9, 9, 4, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1];
var zip = d3.zip(line1, line2, line3).reduce(function(a, c, i) {
const every = c.every(function(e) {
return e === c[0]
})
if (every) a.push(i);
return a;
}, []);
console.log(zip)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
const [longer, shorter] = line1.length > line2.length ? [line1, line2] : [line2, line1];
const crossIndex = shorter.reduce((crossIndex, value, index) => {
if (crossIndex !== null) {
// already found it! just return
return crossIndex;
}
// find it! return
if (value === longer[index]) return index;
// no found, continue searching
return crossIndex;
}, null)
如果你不介意搜索运行一些额外无用的迭代,那么我们找出哪一行更长或更短的第一步实际上是没有必要的。你在第1行或第2行调用.reduce()
,然后再比较另一个,你仍然会得到相同的结果。