Statistics
d3.min/d3.max/d3.extent
正常編寫min的幾種方式:
- for循環(huán)方式
const list = [2,4,1,4];
let min;
list.forEach((val, i) => {
if (i === 0) {
min = val;
} else if (val < min) {
min = val;
}
});
- 使用Math.min方式
const list = [2,4,1,4];
const min = Math.min(...list);
源碼使用了類似for循環(huán)的方式. 需要注意的是: 比較的方式只是用大于/小于, 所以如果數(shù)組由字符串, 而非完全浮點數(shù)組成, min的結(jié)果可能不是所希望的.
extent的源碼和min/max類似, 返回數(shù)組的[min, max]. 如果數(shù)組為空, 則返回[undefined, undefined].
d3.sum
求數(shù)組的和. 源代碼使用for循環(huán)不斷相加.
也可以使用reduce來實現(xiàn)sum:
const list = ['2',4,'11',4];
const sum = list.reduce((a, b) => (+a) + (+b));
d3.mean
求平均值. 會過濾非數(shù)值型. 這里首先需要判斷非數(shù)值型:
isNaN(+val)
加號會將val轉(zhuǎn)換為數(shù)值型. 如果不是數(shù)值型, 會轉(zhuǎn)換為NaN.
過濾掉非數(shù)值型后, 使用sum / count即可.
d3.median
求中位數(shù). 這里調(diào)用了d3.quantile來計算中位數(shù).
d3.variance
求樣本方差.
d3.deviation
求標(biāo)準(zhǔn)差.
Search
d3.scan
求給定數(shù)組的最小值, 但允許提供比較函數(shù)(這點不同于d3.min). 源代碼中關(guān)鍵部分的代碼:
while (++i < n) {
if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {
xj = xi, j = i;
}
}
- 將比較后的最小值存儲在xj中, 然后索引遞增進行排序.
- compare(xj, xj) !== 0用于過濾undefined, null和NaN.
const array = [{foo: 42}, {foo: 91}];
d3.scan(array, function(a, b) { return a.foo - b.foo; }); // 0
d3.scan(array, function(a, b) { return b.foo - a.foo; }); // 1
d3.bisector
這里使用了二分查找法:
left: function(a, x, lo, hi) {
if (lo == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) < 0) lo = mid + 1;
else hi = mid;
}
return lo;
},
d3.ascending/d3.descending
比較兩個數(shù)的大小.
export default function(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
JavaScript中NaN比較特殊, 它不能進行比較. 任何和NaN比較的操作均為false.