【问题标题】:Sort object keys with a sorted array使用排序数组对对象键进行排序
【发布时间】:2018-09-06 12:12:15
【问题描述】:

我有以下按字母顺序对对象进行排序的代码,我想摆脱字母顺序并按我自己选择的顺序进行排序。

var obj = {
  c: "see",
  a: "ay",
  b: "bee",
  d: "dee"
};

console.log("Object order:");
var key, keys = [];
for (key in obj) {
  keys.push(key);
}
console.log(keys.map(function(key) { return key + ": " + obj[key];}).join(", "));

console.log("Sorted order:");
keys = Object.keys(obj).sort()
console.log(keys.map(function(key) { return key + ": " + obj[key];}).join(", "));

上面将输出 a、b、c、d 的对象顺序 - 但假设我希望数组有自己的顺序,例如

var sortedArray = ['b','c','d','a'];

那么我怎么知道将这个sortedArray 实现到我的.sort 中?

预期结果:

var newObj = {
  b: "bee",
  c: "cee",
  d: "dee",
  a: "ay"
};

谢谢

【问题讨论】:

标签: javascript arrays object lodash


【解决方案1】:

这是一种非常奇怪的排序模式,但如你所愿,我创建了一个名为 CustomOrderBy 的函数,它将根据键数组进行排序。

类似这样的:

  1. 您有一个数组,其中包含您想要从头到尾排序的键,就像您已经拥有的一样 (sortedArray)。然后将此数组传递给函数。

  2. 该函数然后循环遍历 obj 键并获取它的第一个字母以检查它是否与键的 arra 匹配,获取其索引。根据索引进行排序。

  3. 排序后,然后它创建一个新的obj,并按照它在之前使用的sort函数中创建的顺序设置键和值

请查看代码以更好地理解它。

var sortedArray = ['b', 'c', 'd', 'a'];

var obj = {
  c: "see",
  a: "ay",
  b: "bee",
  d: "dee"
};

function CustomOrderBy(keyOrder){
  let keysSorted = Object.keys(obj).sort(function(keyA, keyB) {
    let idxA = keyOrder.indexOf(keyA[0]);  
    let idxB = keyOrder.indexOf(keyB[0]);
    if (idxA > idxB){
      return 1
    }else if(idxA < idxB){
      return -1
    }else{
      return 0;
    }  
  });

  let sorted = {};
  for (var key of keysSorted){
    if (obj[key] != null){
      sorted[key] = obj[key];
    }
  }
  return sorted;
}
console.log(CustomOrderBy(sortedArray))

【讨论】:

  • 非常感谢,这太完美了。当我的密钥更改为 2 个字符时,我不得不稍微采用它。太棒了。
【解决方案2】:

您可以将自定义排序函数传递给sort() API。请看下面的例子:

var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic', value: 13 },
  { name: 'Zeros', value: 37 }
];
    
// sort by value
items.sort(function (a, b) {
  return a.value - b.value;
});

// sort by name
items.sort(function(a, b) {
  var nameA = a.name.toUpperCase(); // ignore upper and lowercase
  var nameB = b.name.toUpperCase(); // ignore upper and lowercase
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }

  // names must be equal
  return 0;
});

console.log(items)

【讨论】:

    【解决方案3】:

    使用使用indexOf()的自定义排序器

    var sortedArray = ['b', 'c', 'd', 'a'];
    
    var obj = {
      c: "see",
      a: "ay",
      b: "bee",
      d: "dee"
    };
    
    
    var keys = Object.keys(obj).sort(function(a, b) {
      // TODO - cases where not in sortedArray
      return sortedArray.indexOf(a) - sortedArray.indexOf(b)
    });
    
    
    console.log(keys)

    【讨论】:

    • 你的代码不是和console.log(sortedArray)一样吗?
    • @CalvinNunes 它肯定是。老实说,不太确定 OP 想要做什么
    • 我认为他想对一些数组进行排序,其顺序与默认顺序不同(字典字母顺序),但他没有指定标准,所以很难知道他真正想要什么
    • 是的,这很棒 - 它对键进行排序,但它不维护键数组中的值。输出只是按顺序输出键。 cee、ay、bee 和 dee 不见了
    • Javascript 对象没有顺序。整个事情看起来像XY problem
    【解决方案4】:

    对不起,如果排序顺序和对象之间的关系是一对一的,为什么我们不做这样的事情(从排序顺序数组开始):

    var myObject = {c: "see", a: "ay", b: "bee", d: "dee"};
    var sortOrder = ['b','c','d','a'];
    
    const mySort = (obj, order) => order.reduce((r,c) => (r[c] = obj[c], r), {})
    
    console.log(mySort(myObject, sortOrder))

    由于只使用了一个reduce,它看起来会更加简洁和简单。

    【讨论】:

      【解决方案5】:

      您可以像我在下面那样创建一个函数。并传递您的对象,它会将排序后的对象返回给您。

          var obj = {
              c: "see",
              a: "ay",
              b: "bee",
              d: "dee"
          };
      
      
          function sortObject(obj)
          {
              var keys = [];
              var outputObj = {};
      
              for (key in obj)
              {
                  keys.push(key);
              }
      
              keys.sort();
      
              for(var i=0; i<keys.length; i++){
                  outputObj[keys[i]] = obj[keys[i]];
              }
      
              return outputObj;
          }
          
          console.log(sortObject(obj));

      【讨论】:

      • 你的函数做的正是提问者不想要的,即sort() 按字母顺序,他想要自己的排序顺序,而不是默认的。
      最近更新 更多