【问题标题】:Sorting array by key object按关键对象对数组进行排序
【发布时间】:2015-04-24 09:46:45
【问题描述】:

我有以下结构:

var participant0 = {
    name : "",
    nickname : "",
    number "99999"
} ;

var participant1 = {
    name : "bbb",
    nickname : "",
} ;

var participant2 = {
    name : "",
    nickname : "aaa"
} ;

var participant3 = {
    name : "ccc",
    nickname : ""
} ;

我有一个包含结构实例的数组:

var array = [participant0, participant3, participant1, participant2];

我想按字母排序这个数组。第一个名字,第二个昵称。如果这两个键不存在,我想检查数字键并将这个元素放在排序列表的末尾。

预期结果:

var array = [participant2, participant1, participant3, participant0];

(按“aaa”、“bbb”、“ccc”、“9999”对对象进行排序)

以下代码可以正常按名称或昵称排序,但如果有数字键,我不知道如何将项目放在排序列表的末尾:

fav_list.sort(function(x, y) {
              return (x.participant.name || x.participant.nickname).localeCompare(y.participant.name || y.participant.nickname);
            });

【问题讨论】:

  • 为什么participant2在结果中应该在participant1之前?真的nickname="aaa" < nickname=""吗?
  • 比较“2”和“10”时,哪个先出现?
  • @hindmost nickname="aaa" < name="bbb"。这些排序规则很奇怪吗?是的,他们是,但这正是 OP 想要的。

标签: javascript jquery arrays sorting


【解决方案1】:

我觉得应该这样,看代码中的cmets:

fav_list.sort(function(x, y) {
    var xvalue = x.participant.name || x.participant.nickname;
    var yvalue = y.participant.name || y.participant.nickname;
    // By name if both have names
    if (xvalue && yvalue) {
        return xvalue.localeCompare(yvalue);
    }
    // Names always come before numbers
    if (xvalue) {
        return -1;
    }
    if (yvalue) {
        return 1
    }
    // Otherwise compare numbers
    return (x.participant.number || 0) - (y.participant.number || 0);
});

您可能希望在最后一行使用默认数字(零)。

请注意,您显示的数组与该代码不太匹配,因为该数组直接使用参与者,但代码期望参与者位于对象的 participant 属性上。

带有略微调整的数组的实时示例,以及一种方便的方式来判断我们最终的顺序:

var participant0 = {
  name: "",
  nickname: "",
  number: "99999",
  debug: 0
};

var participant1 = {
  name: "bbb",
  nickname: "",
  debug: 1
};

var participant2 = {
  name: "",
  nickname: "aaa",
  debug: 2
};

var participant3 = {
  name: "ccc",
  nickname: "",
  debug: 3
};

var array = [
  {
    participant: participant0
  },
  {
    participant: participant3
  },
  {
    participant: participant1
  },
  {
    participant: participant2
  }
];

array.sort(function(x, y) {
  var xvalue = x.participant.name || x.participant.nickname;
  var yvalue = y.participant.name || y.participant.nickname;
  // By name if both have names
  if (xvalue && yvalue) {
    return xvalue.localeCompare(yvalue);
  }
  // Names always come before numbers
  if (xvalue) {
    return -1;
  }
  if (yvalue) {
    return 1
  }
  // Otherwise compare numbers
  return (x.participant.number || 0) - (y.participant.number || 0);
});
array.forEach(function(entry) {
  snippet.log(entry.participant.debug);
});
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

【讨论】:

  • 工作正常!谢谢:)
  • 有时,此代码返回:Uncaught TypeError: xvalue.localCompare is not a function
  • @wawanopoulos:应该是localeCompare,而不是localCompare。 sn-p 是正确的,但顶部的代码示例是错误的,对此感到抱歉 - 现在已修复。
【解决方案2】:

不要一次做所有事情。

fav_list.sort(function(x,y) {
    var xname = x.name || x.nickname || "\uffff"+x.number;
    var yname = y.name || y.nickname || "\uffff"+y.number;
    return xname.localeCompare(yname);
});

"\uffff" 是强制数字放在最后;)

【讨论】:

  • 我会警惕 localeCompare 和 \uffff 在全球范围内工作。但这仍然非常有创意和简洁。 :-) 在末尾按字母顺序对数字进行排序(所以 2 在 10 之前),但如果它很重要,很容易调整以处理它。
【解决方案3】:

代码可以写成:

\uffff 直接解释为想要的 字符串,整个序列实现为单个字符

var participant0 = {
    name : "",
    nickname : "",
    number: "99999"
} ;

var participant1 = {
    name : "bbb",
    nickname : ""
} ;

var participant2 = {
    name : "",
    nickname : "aaa"
} ;

var participant3 = {
    name : "ccc",
    nickname : ""
} ;
var array = [participant0, participant3, participant1, participant2];
console.log(array.sort(function(x,y) {
    var val1 = x.name || x.nickname || "\uffff"+x.number;
    var val2 = y.name || y.nickname || "\uffff"+y.number;
    return xname.localeCompare(val2);
}))
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"&gt;&lt;/script&gt;

【讨论】:

    【解决方案4】:
    function sortObject(object) { // sort Object by key
        var sorted = {},
            key, a = [];
        for (key in object) {
            if (object.hasOwnProperty(key)) {
                a.push(key);
            }
        }
        a.sort();
        for (key = 0; key < a.length; key++) {
            sorted[a[key]] = object[a[key]];
        }
        return sorted;
    }
    
    function sortArray(arr){//sort array of objects
        var array=[];
        for(var i=0;i<arr.length;i++){
            array.push(sortObject(arr[i]));
        }
        return array;
    }
    
    var arr=[{a:'1',c:'2',b:'3'},{c:'1',b:'2',a:'3'}];
    console.log('===>',sortArray(arr));
    

    【讨论】:

      【解决方案5】:

      你可以尝试解决方法。

        var numbers = [];    
      fav_list.sort(function(x, y) {  
                   if(!isNaN(x)){
                    numbers.push(x);
                   continue;
                   }
                        return (x.participant.name || x.participant.nickname).localeCompare(y.participant.name || y.participant.nickname);
                      });
          fav_list.push(numbers);
      

      【讨论】:

        猜你喜欢
        • 2020-07-11
        • 2021-06-06
        • 1970-01-01
        • 2016-12-23
        • 1970-01-01
        • 1970-01-01
        • 2018-07-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多