简体   繁体   English

如何按字符串值对数组中的对象数组进行排序?

[英]How can I sort an array of objects in an array by string value?

I have an array of objects. 我有一个对象数组。

In each object, I'm targeting a property called "myLevel". 在每个对象中,我都针对一个名为“ myLevel”的属性。 The values for this property vary in the following string syntax: 此属性的值在以下字符串语法中有所不同:

 [
 {myLevel : 'CAT I #4'},
 {myLevel : 'CAT I #6'},
 {myLevel : 'CAT I #2'},
 {myLevel : 'CAT II #15'},
 {myLevel : 'CAT III #1'},
 {myLevel : 'CAT II #7'},

   ]

How can I sort the array so that the objects are rearranged in ascending order like so: 我如何对数组进行排序,以使对象按升序重新排列,如下所示:

[
 {myLevel : 'CAT I #2'},
 {myLevel : 'CAT I #4'},
 {myLevel : 'CAT I #6'},
 {myLevel : 'CAT II #7'},
 {myLevel : 'CAT II #15'},
 {myLevel : 'CAT III #1'}
   ] 

Use Array.sort, and in the passed function, split the strings by the # sign, compare the first half as string, if even, compare second half as int with call parseInt. 使用Array.sort,并在传递的函数中,用#号分割字符串,将前半部分与字符串进行比较,如果是偶数,则通过调用parseInt将后半部分与int进行比较。
In reality, this will be slow if there are a lot of records. 实际上,如果有很多记录,这将很慢。 You should really store the records as an object with 2 integers for cat and level. 您实际上应该将记录存储为一个对象,其中cat和level为2个整数。 Thia will make sorting more efficient. Thia将使分拣更加有效。 You can override the toString function to display it the way you like. 您可以重写toString函数以您喜欢的方式显示它。

Use RegEx to match the parts, then check those parts individually 使用RegEx匹配零件,然后分别检查这些零件

var arr = [
 {myLevel : "CAT I #4"},
 {myLevel : "CAT I #6"},
 {myLevel : "CAT I #2"},
 {myLevel : "CAT II #15"},
 {myLevel : "CAT III #1"},
 {myLevel : "CAT II #7"}
];

var sorted = arr.sort(function(a,b){
 var left = a.myLevel.match(/CAT (I+) #([0-9]+)/);
 var right = b.myLevel.match(/CAT (I+) #([0-9]+)/);
 if(left[1].length==right[1].length){
  return left[2]-right[2];
 }else return left[1].length-right[1].length;
});

The match returns match归来

[0] whole matched string
[1] all the `I`'s
[2] the number after the #

The first if is to check if the I count is the same, if it is we need to check by the number. 第一个if是检查I计数是否相同,如果是,则需要按数字检查。

If we need to check by the number, we just need to return the difference between them. 如果需要按数字检查,只需返回它们之间的差额即可。

If we don't need to check by the number we just need to return the difference between the amount of I 's 如果我们不需要按数字检查,我们只需要返回I的数量之间的差

Use sort with a comparator. 与比较器一起使用sort

// assume we want to have arbitrary roman numerals - we should have some form of lookup
var numeralLookup = {
  I: 1,
  II: 2,
  III: 3,
  IV: 4
} //etc

// helper function - parse Roman Numeral from your string
function getNumeral(str) {
  return str.split()[1]
}

// helper function - parse number after '#' from your string
function getNumber(str) {
  return parseInt(str.slice(str.indexOf('#') + 1))
}

// sort
arr.sort(function(a, b) {
  var aNum = numeralLookup[getNumeral(a.myLevel)];
  var bNum = numeralLookup[getNumeral(b.myLevel)];

  return aNum === bNum ? getNumber(a.myLevel) - getNumber(b.myLevel) : aNum - bNum;
})

Believe it or not a faster alternative to Array.sort is Underscore's sortBy function. 相信或不相信Array.sort的更快替代方法是Underscore的sortBy函数。 Check out their documentation here . 在此处查看其文档 The library has all sorts of great utilities for doing stuff like this. 该库具有用于执行此类操作的各种强大实用程序。

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.sortBy(stooges, 'name');
=> [{name: 'curly', age: 60}, {name: 'larry', age: 50}, {name: 'moe', age: 40}];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM