use*_*611 1 javascript arrays d3.js
我正在尝试将map.set(key, value)用于特定数据集 - 并将其分配给变量mapdata - 而不是在我将 csv 排队时指定它。
即,而不是:
d3.queue()
.defer(d3.json, 'counties.json')
.defer(d3.csv, 'employmentdata.csv') function(d) {
d3.map()
.set(d.county, +d.rate);
})
.await(ready);
Run Code Online (Sandbox Code Playgroud)
我想要更多的东西
var mapdata = d3.map(data)
.set(function(d) {d.county}, function(d) {d.rate});
Run Code Online (Sandbox Code Playgroud)
除了代码没有返回我想要的。索引是键而不是县,值包括整个数据集而不仅仅是比率。我将如何解决这个问题?
提前致谢
当这样使用时:
.defer(d3.csv, 'employmentdata.csv') function(d) {
map
.set(d.county, +d.rate);
})
Run Code Online (Sandbox Code Playgroud)
map.set为 csv 中的每一行调用 with 回调函数,并单独设置每个键和值。如果你已经有一个数据数组,你可以用一个 forEach 循环来模拟它:
.defer(d3.csv, 'employmentdata.csv') function(d) {
map
.set(d.county, +d.rate);
})
Run Code Online (Sandbox Code Playgroud)
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map();
data.forEach(function(d) {
map.set(d.key, d.value);
})
console.log(map.get("A"));Run Code Online (Sandbox Code Playgroud)
我们可以扩展它来操作键和值,因为 row 函数或 forEach 循环允许访问 datum d,我们实际上不需要将操作包含在函数中:
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>Run Code Online (Sandbox Code Playgroud)
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map();
data.forEach(function(d,i) {
map.set(d.key+"-"+i, d.value*2);
})
console.log(map.get("A-0"));Run Code Online (Sandbox Code Playgroud)
你的第二个例子:
var mapdata = d3.map(data)
.set(function(d) {d.county}, function(d) {d.rate});
Run Code Online (Sandbox Code Playgroud)
这将不起作用,因为.set它只被调用一次,并且d没有定义。事实上,这些函数根本不会被调用。
在我们查看 set 方法中的函数之前,让我们仔细看一下第一行:
var mapdata = d3.map(data)
Run Code Online (Sandbox Code Playgroud)
d3.map 需要两个参数,一个定义数据数组,另一个定义键。由于您不提供密钥,因此使用默认密钥,索引:
d3.map([object[, key]]) <>
构建新地图。如果指定了对象,则将指定对象中的所有可枚举属性复制到此映射中。指定的对象也可以是数组或其他映射。可以指定一个可选的键函数来计算数组中每个值的键。(来源)
因此,您看到的行为不是来自.set方法,而是来自默认索引:
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>Run Code Online (Sandbox Code Playgroud)
var mapdata = d3.map(data)
.set(function(d) {d.county}, function(d) {d.rate});
Run Code Online (Sandbox Code Playgroud)
那么.set在你的例子中做了什么?它正在向您的数据集添加一个新的值键对,让我们仔细看看之前和之后的地图:
var mapdata = d3.map(data)
Run Code Online (Sandbox Code Playgroud)
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map(data);
console.log(map.get(0));Run Code Online (Sandbox Code Playgroud)
这是一个有趣的行为,不仅console.log在 set 方法中没有调用 s,这两个函数被添加为数组中的键值对。很容易错过(主要是由于堆栈片段的日志记录),但这是地图的补充:
"$function (d) { console.log(d); }": function (d) { console.log(d); },
set 方法只会添加一个键值对,它不会修改现有的键值对(除非覆盖一个)。这就是为什么 .set 将在行函数或 forEach 循环中工作,但在设置多个键/值对时则不然。
虽然作为键的函数被强制转换为字符串,但您可以将函数作为值嵌入:
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>Run Code Online (Sandbox Code Playgroud)
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map(data);
console.log(map);
console.log("---------------");
map.set(function(d) { console.log(d); },
function(d) { console.log(d); })
console.log(map);Run Code Online (Sandbox Code Playgroud)
加起来
因此,如果您想使用键和整个对象作为值创建地图,您可以使用:
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>Run Code Online (Sandbox Code Playgroud)
var data = [
{key: "A", value: 100},
]
var map = d3.map(data);
map.set("B",function() { return "Hello"; })
console.log(map.get("B")());Run Code Online (Sandbox Code Playgroud)
但是如果你想为每个键指定一个特定的值(而不是数据数组项),使用 forEach 循环会更容易(如本答案的第一个片段所示):
var map = d3.map()
data.forEach(function(d) {
map.set(d.key,d.value)
})
Run Code Online (Sandbox Code Playgroud)
如果要在此处的 set 方法中使用函数,则需要执行该函数并具有返回值(在第二个示例/所需代码中都没有),您需要函数的输出,而不是函数本身:
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>Run Code Online (Sandbox Code Playgroud)
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map(data, function(d) { return d.key; });
console.log(map.get("A"));Run Code Online (Sandbox Code Playgroud)
最后一点,您的初始(参考/起点)代码块设置不正确,d3.map() 创建了一个新地图。我们不想为每一行创建一个新地图,我们想创建一次地图,然后为每一行使用 set。
因此:
d3.queue()
.defer(d3.json, 'counties.json')
.defer(d3.csv, 'employmentdata.csv') function(d) {
d3.map()
.set(d.county, +d.rate);
})
.await(ready);
Run Code Online (Sandbox Code Playgroud)
应该是这样的:
var map = d3.map(); // create a map.
d3.queue()
.defer(d3.json, 'counties.json')
.defer(d3.csv, 'employmentdata.csv') function(d) {
map // use that same map for each row.
.set(d.county, +d.rate);
})
.await(ready);
Run Code Online (Sandbox Code Playgroud)
上面的片段使用相同的方法,创建一个映射,并调用.set数组中的每个项目。
相反,类似 :d3.map().get(d.property)不会返回任何内容,因为您刚刚创建了一个空的新地图d3.map()。