使用 d3.js 的下拉 select 列表中数据的唯一对?
Unique pairs from data in a drop down select list using d3.js?
我想用对象中的唯一值填充下拉列表(select 标记)。
这是包含数据的对象:
[
{
"code": 1,
"abbr": "BR",
"vote": 49277010
},
{
"code": 1,
"abbr": "BR",
"vote": 31342051
},
{
"code": 43,
"abbr": "RS",
"vote": 3353623
},
{
"code": 31,
"abbr": "MG",
"vote": 3037957
},
{
"code": 31,
"abbr": "MG",
"vote": 5017922
},
{
"code": 35,
"abbr": "SP",
"vote": 2650440
},
{
"code": 42,
"abbr": "SC",
"vote": 2603665
},
{
"code": 1,
"abbr": "BR",
"vote": 71347057
},
{
"code": 26,
"abbr": "PE",
"vote": 2309104
}
]
下面是我获取数据以构建下拉列表的方式:
//initialize the dropdown
var dropdown = d3.select("#sel")
dropdown
.selectAll('myOptions')
.data(data)
.enter()
.append('option')
.text(function (d) { return d.abbr; }) //text showed in the options
.attr("value", function (d) { return d.code; }) //values returned by each option
问题是显示了重复的值,而不是每个 code/abbr 只显示一个值,如下所示:
<select id="sel">
<option value="1">BR</option>
<option value="1">BR</option>
<option value="43">RS</option>
<option value="31">MG</option>
<option value="31">MG</option>
<option value="35">SP</option>
<option value="42">SC</option>
<option value="1">BR</option>
<option value="26">PE</option>
</select>
如何过滤数据以在选项中仅包含唯一值?
<select id="sel">
<option value="1">BR</option>
<option value="43">RS</option>
<option value="31">MG</option>
<option value="35">SP</option>
<option value="42">SC</option>
<option value="26">PE</option>
</select>
== 编辑 ==
我能够像下面这样使用 set 获得唯一值:
const selectedData = [... new Set(data.map(d => d.abbr))].sort();
但是我只能使用 abbr。我怎样才能得到 code?
已尝试 [... new Set(data.map(d => [d.abbr, d.code))]
,但没有成功,因为这会再次创建一个包含所有未过滤数据的数组对象。
d3 v7 中的新功能是 flatGroup
,它将 return 一个数组,其中包含唯一的 code
和 abbr
对以及关联的数组对象:
d3.flatGroup(data, d => d.code, d => d.abbr);
如果您使用的是早期版本,那么您可以使用 Map
来获得类似的结果(但是 没有 关联的数组对象):
const uniqueData = Array.from(
data.reduce((a, c) => {
a.set(c.code, c.abbr);
return a;
}, new Map())
);
console.log(uniqueData);
下面的工作示例使用 flatGroup
:
const uniqueData = d3.flatGroup(data, d => d.code, d => d.abbr);
console.log(uniqueData);
//initialize the dropdown
var dropdown = d3.select("#sel")
dropdown
.selectAll('myOptions')
.data(uniqueData)
.enter()
.append('option')
.text(function (d) { return d[1]; }) //text showed in the options
.attr("value", function (d) { return d[0]; }) //values returned by
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.3.0/d3.min.js"></script>
<select id="sel">
</select>
<script>
const data = [
{
"code": 1,
"abbr": "BR",
"vote": 49277010
},
{
"code": 1,
"abbr": "BR",
"vote": 31342051
},
{
"code": 43,
"abbr": "RS",
"vote": 3353623
},
{
"code": 31,
"abbr": "MG",
"vote": 3037957
},
{
"code": 31,
"abbr": "MG",
"vote": 5017922
},
{
"code": 35,
"abbr": "SP",
"vote": 2650440
},
{
"code": 42,
"abbr": "SC",
"vote": 2603665
},
{
"code": 1,
"abbr": "BR",
"vote": 71347057
},
{
"code": 26,
"abbr": "PE",
"vote": 2309104
}
];
</script>
我想用对象中的唯一值填充下拉列表(select 标记)。
这是包含数据的对象:
[
{
"code": 1,
"abbr": "BR",
"vote": 49277010
},
{
"code": 1,
"abbr": "BR",
"vote": 31342051
},
{
"code": 43,
"abbr": "RS",
"vote": 3353623
},
{
"code": 31,
"abbr": "MG",
"vote": 3037957
},
{
"code": 31,
"abbr": "MG",
"vote": 5017922
},
{
"code": 35,
"abbr": "SP",
"vote": 2650440
},
{
"code": 42,
"abbr": "SC",
"vote": 2603665
},
{
"code": 1,
"abbr": "BR",
"vote": 71347057
},
{
"code": 26,
"abbr": "PE",
"vote": 2309104
}
]
下面是我获取数据以构建下拉列表的方式:
//initialize the dropdown
var dropdown = d3.select("#sel")
dropdown
.selectAll('myOptions')
.data(data)
.enter()
.append('option')
.text(function (d) { return d.abbr; }) //text showed in the options
.attr("value", function (d) { return d.code; }) //values returned by each option
问题是显示了重复的值,而不是每个 code/abbr 只显示一个值,如下所示:
<select id="sel">
<option value="1">BR</option>
<option value="1">BR</option>
<option value="43">RS</option>
<option value="31">MG</option>
<option value="31">MG</option>
<option value="35">SP</option>
<option value="42">SC</option>
<option value="1">BR</option>
<option value="26">PE</option>
</select>
如何过滤数据以在选项中仅包含唯一值?
<select id="sel">
<option value="1">BR</option>
<option value="43">RS</option>
<option value="31">MG</option>
<option value="35">SP</option>
<option value="42">SC</option>
<option value="26">PE</option>
</select>
== 编辑 ==
我能够像下面这样使用 set 获得唯一值:
const selectedData = [... new Set(data.map(d => d.abbr))].sort();
但是我只能使用 abbr。我怎样才能得到 code?
已尝试 [... new Set(data.map(d => [d.abbr, d.code))]
,但没有成功,因为这会再次创建一个包含所有未过滤数据的数组对象。
d3 v7 中的新功能是 flatGroup
,它将 return 一个数组,其中包含唯一的 code
和 abbr
对以及关联的数组对象:
d3.flatGroup(data, d => d.code, d => d.abbr);
如果您使用的是早期版本,那么您可以使用 Map
来获得类似的结果(但是 没有 关联的数组对象):
const uniqueData = Array.from(
data.reduce((a, c) => {
a.set(c.code, c.abbr);
return a;
}, new Map())
);
console.log(uniqueData);
下面的工作示例使用 flatGroup
:
const uniqueData = d3.flatGroup(data, d => d.code, d => d.abbr);
console.log(uniqueData);
//initialize the dropdown
var dropdown = d3.select("#sel")
dropdown
.selectAll('myOptions')
.data(uniqueData)
.enter()
.append('option')
.text(function (d) { return d[1]; }) //text showed in the options
.attr("value", function (d) { return d[0]; }) //values returned by
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.3.0/d3.min.js"></script>
<select id="sel">
</select>
<script>
const data = [
{
"code": 1,
"abbr": "BR",
"vote": 49277010
},
{
"code": 1,
"abbr": "BR",
"vote": 31342051
},
{
"code": 43,
"abbr": "RS",
"vote": 3353623
},
{
"code": 31,
"abbr": "MG",
"vote": 3037957
},
{
"code": 31,
"abbr": "MG",
"vote": 5017922
},
{
"code": 35,
"abbr": "SP",
"vote": 2650440
},
{
"code": 42,
"abbr": "SC",
"vote": 2603665
},
{
"code": 1,
"abbr": "BR",
"vote": 71347057
},
{
"code": 26,
"abbr": "PE",
"vote": 2309104
}
];
</script>