JavaScript按字母顺序创建索引映射

时间:2017-10-08 01:51:48

标签: javascript sorting d3.js

我有一个csv被加载到用D3渲染的和弦图中:

origin    destination    value
banana    kiwi           10
apple     banana         5
pear      kiwi           12

此数据以这种格式传递:

console.log(data)
>> 0: {origin: "banana", destination: "kiwi", value: 10}
   1: {origin: "apple", destination: "banana", value: 5}
   2: {origin: "pear", destination: "kiwi", value: 12}

我正在创建一个origindestination矩阵,其中value填充矩阵值。第一步是创建一个将水果名称与索引联系起来的映射:

var nameToIndex = {},
      names = [],
      matrix = [],
      n = 0,

  function recordName(name){
    if( !(name in nameToIndex) ){
            nameToIndex[name] = n++;
            names.push(name);
          }
        }

  data.forEach(function (d){
    recordName(d.origin);
    recordName(d.destination);
  });

运行此命令后,这里有示例console.log()命令:

console.log(nameToIndex[apple])
>> 2

console.log(nameToIndex[kiwi])
>> 1

名称不按字母顺序组织。我如何对名称进行排序,以便它们的索引也被排序?以前命令的结果应为:

console.log(nameToIndex[apple])
>> 0

console.log(nameToIndex[kiwi])
>> 2

Apple是按字母顺序排列的第一个水果,而kiwi是按字母顺序排列的第三个水果。

我尝试将names.sort()添加到recordName()函数,但这只是排序names(可预测),并没有更改nameToIndex的索引。

如何对nameToIndex进行排序,以便对键和值进行排序?

1 个答案:

答案 0 :(得分:1)

根据your comment,你想要的只是一个对象,所有水果作为关键字,其字母位置为值。

在这种情况下,我们首先获得所有成果......

var allFruits = [...new Set(data.map(function(d) {
    return d.origin
}).concat(data.map(function(d) {
    return d.destination
})))]

...并对生成的数组进行排序:

.sort(function(a, b) {
    return d3.ascending(a, b)
});

之后,我们只使用nameToIndex填充forEach

allFruits.forEach(function(d, i) {
    nameToIndex[d] = i;
});

以下是演示:

var csv = `origin,destination,value
banana,kiwi,10
apple,banana,5
pear,kiwi,12`;

var data = d3.csvParse(csv);

var nameToIndex = {};

var allFruits = [...new Set(data.map(function(d) {
  return d.origin
}).concat(data.map(function(d) {
  return d.destination
})))].sort(function(a, b) {
  return d3.ascending(a, b)
});

allFruits.forEach(function(d, i) {
  nameToIndex[d] = i;
});

console.log(nameToIndex)
<script src="https://d3js.org/d3.v4.min.js"></script>