【问题标题】:Sort JSON by a given order via Array (JavaScript, D3)通过数组(JavaScript,D3)按给定顺序对 JSON 进行排序
【发布时间】:2016-07-18 17:10:22
【问题描述】:

我想从表示名称/值列的数组中按特定顺序对 JSON 数组进行排序。一个例子是:

data = [
  {
     First: "John",
     Last: "Doe",
     Age: 23
  },
  {
     First: "Sue",
     Last: "San",
     Age: 13
  },
  {
     First: "Kyle",
     Last: "Wafer",
     Age: 87
  }
];
var sortBy = ["San", "Wafer", "Doe"];

所以我的输出是:

  var newData = [
  {
     First: "Sue",
     Last: "San",
     Age: 13,
  },
  {
     First: "Kyle",
     Last: "Wafer",
     Age: 87,
  },

  {
     First: "John",
     Last: "Doe",
     Age: 23,
  }
];

是否可以使用 D3.js 或基本 JavaScript 实现而不需要复杂的 for 循环?谢谢。

【问题讨论】:

  • @Tibrogargan 不完全...这是不同的
  • 是的,有可能。您具体尝试了什么?
  • @epascarello - 足够接近,不是吗?特别是三联画的回答。

标签: javascript arrays json d3.js


【解决方案1】:

您可以使用对象作为排序顺序并按此值对其进行排序。

var data = [{ First: "John", Last: "Doe", Age: 23 }, { First: "Sue", Last: "San", Age: 13 }, { First: "Kyle", Last: "Wafer", Age: 87 }],
    sortBy = ["San", "Wafer", "Doe"],
    sortByObj = {};

sortBy.forEach(function (a, i) {
    sortByObj[a] = i + 1;
});

data.sort(function (a, b) {
    return (sortByObj[a.Last] || 0) - (sortByObj[b.Last] || 0);
});

console.log(data);

【讨论】:

    【解决方案2】:

    可以像这样在数组上使用.sort() 方法:

    data.sort(function (a, b) {return sortBy.indexOf(a.Last) - sortBy.indexOf(b.Last)})
    

    【讨论】:

    • 应该真正使用减法进行数字排序
    【解决方案3】:

    您可以使用 sort 并使用 indexOf 来获取位置,但这意味着在每次排序时您都在执行内部循环来获取位置。

    不使用排序,您可以先通过键索引元素,然后循环遍历顺序。

    data = [
      {
         First: "John",
         Last: "Doe",
         Age: 23
      },
      {
         First: "Sue",
         Last: "San",
         Age: 13
      },
      {
         First: "Kyle",
         Last: "Wafer",
         Age: 87
      }
    ];
    var sortBy = ["San", "Wafer", "Doe"];
    
    var temp = data.reduce( function(obj, item) {
        obj[item.Last] = item;
        return obj;
    }, {});
    var result = sortBy.map( function(key){ return temp[key]; });
    console.log(result);

    但是这种技术会失败的地方是它会重复两个键。为了解决这个问题,可以使用数组来完成。

    data = [
      {
         First: "John",
         Last: "Doe",
         Age: 23
      },
      {
         First: "Jane",
         Last: "Doe",
         Age: 20
      },  
      {
         First: "Sue",
         Last: "San",
         Age: 13
      },
      {
         First: "Kyle",
         Last: "Wafer",
         Age: 87
      }
    ];
    var sortBy = ["San", "Wafer", "Doe"];
    
    var temp = data.reduce( function(obj, item) {
        if(!obj[item.Last]) obj[item.Last]=[];
        obj[item.Last].push(item);
        return obj;
    }, {});
    var result = sortBy.reduce( function(arr, item){ return arr.concat(temp[item]); return arr }, []);
    console.log(result);

    我确信他们是一种更好的连接方式,但做得很快。

    您应该根据您的真实数据运行一些性能测试,看看哪些性能最好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多