Sort array of objects by string property value
我有一个javascript对象数组:
1 2 3 4 5 | var objs = [ { first_nom: 'Lazslo', last_nom: 'Jamf' }, { first_nom: 'Pig', last_nom: 'Bodine' }, { first_nom: 'Pirate', last_nom: 'Prentice' } ]; |
如何按javascript中
我知道
- 这个脚本允许您这样做,除非您想编写自己的比较函数或排序器:thomasfrank.se/sorting_Things.html
编写自己的比较函数很容易:
1 2 3 4 5 6 7 8 9 | function compare(a,b) { if (a.last_nom < b.last_nom) return -1; if (a.last_nom > b.last_nom) return 1; return 0; } objs.sort(compare); |
或内联(c/o marco demaio):
1 | objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0)); |
- 或inline:objs.sort(函数(a,b)返回(a.last_nom>b.last_nom)?1:(b.姓氏>a.姓氏)- 1:0);
- 非常感谢,但我很难理解函数遵循的逻辑…什么是A&B?他们是第一和第二,第二,第三,第三,第四????
- 官方文档:developer.mozilla.org/en/javascript/reference/global_objects&zwnj;&8203;/&hellip;
return a.last_nom.localeCompare(b.last_nom) 也会起作用。- 如果想让coffeescript为这个:objs.sort(a,b)->返回(a.last_nom>b.last_nom)?1:(b.姓氏>a.姓氏)- 1:0)
- 对于寻找字段为数字的排序的那些,比较函数体:
return a.value - b.value; (asc) - MDN页面上有很多提示:developer.mozilla.org/en/docs/web/javascript/reference/&hellip;
- @马可德马约1〔2〕真强制数为1,假0。
- 以下是两种很好的方法:(1)按日期对javascript对象数组排序,(2)按日期对javascript对象数组排序
- 这个答案最大的问题是在处理可能的
null 或未定义的属性时缺乏细节。我已经更新了它,包括一个解释和详细的实现。 - 如果排序计算很昂贵,排序如何阻止重新比较相同的值呢?
- 我知道创建一个完整的比较函数很冗长,但是man确实可以使遵循逻辑变得更容易。谢谢。
- 因为我们都喜欢三元运算符:
objs.sort(function compare(a,b) { return a.val < b.val ? -1 : a.val > b.val ? 1 : 0; }); 。 - @当在外语中使用重音字符时,cerbrus
localeCompare 是很重要的,而且也更优雅。 - 类型错误:obj.sort不是函数。(在"compare.sort(compare)"中,"obj.sort"未定义)
- @浏览器中的cerbrus localecompare支持IE11+:/
- @LuckyLooke需要IE11作为可选的[,locales][,options]参数;早期版本的IE支持localeCompare函数本身。
- 或者,使用es6样式:objs.sort((a,b)=>(a.last_nom>b.last_nom)?1:(b.姓氏>a.姓氏)- 1:0);
- 回答完全失败,基本例子如
[ { a: 5 }, {a:2}, {}, {a:1} ] 。 - 如果
key 值与小写和大写混合,那么我们可以使该toLowerCase() 生效。否则排序将不起作用。它将对所有以大写开始的值进行排序,然后对小写的值进行排序。 - 在typescript::objs.sort((a:any,b:any)=>return(a.order&;b.order)中re@marcodemaio?(A.订单>B.订单)?1:(B.订单>A.订单)?-1:0)):0;);
- array.sort()不稳定(moz自己说),不能一直工作
- 如果要比较多个属性和重音字符,可以使用
return a.lastname.localeCompare(b.lastname) || a.firstname.localeCompare(b.firstname); 。 - 当订单不区分大小写时,本地比较很重要:A B C…(答案示例区分大小写:a c a b c…)
还可以创建一个动态排序函数,该函数按传递的值对对象进行排序:
1 2 3 4 5 6 7 8 9 10 11 | function dynamicSort(property) { var sortOrder = 1; if(property[0] ==="-") { sortOrder = -1; property = property.substr(1); } return function (a,b) { var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; return result * sortOrder; } } |
所以您可以有这样的对象数组:
1 2 3 | var People = [ {Name:"Name", Surname:"Surname <div class="suo-content">[collapse title=""]<ul><li>请注意,javascript中的属性名称可以是任何字符串,如果属性以"-"开头(极不可能,也可能不是一个好主意),则需要修改dynamicsort函数以使用其他内容作为反向排序指示器。</li><li>我注意到上面例子中的<wyn>dynamicSort()</wyn>将把大写字母放在小写字母之前。例如,如果我有值<wyn>APd</wyn>、<wyn>Aklin</wyn>和<wyn>Abe</wyn>,那么asc排序的结果应该是<wyn>Abe</wyn>、<wyn>Aklin</wyn>、<wyn>APd</wyn>。但以你的例子来说,结果是<wyn>APd</wyn>、<wyn>Abe</wyn>、<wyn>Aklin</wyn>。要纠正这种行为吗?</li><li>@劳埃德银行如果您严格地使用这个字符串,那么您可以使用<wyn>var result = a[property].localeCompare(b[property]);</wyn>,而不是<wyn>var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;</wyn>。</li><li>就像最重要的答案一样,如果存在不完善的属性,这个答案也会失败:<wyn>[ { a: 5 }, {a:2}, {}, {a:1} ]</wyn>。</li><li>@dzh-um,未定义的键应该如何处理?你可以做些不同的事情来实现这一目标。1)获取一个默认值,并将其与<wyn>a[property] || defaultVal</wyn>进行比较。2)如果[属性]为空,则始终返回-1(或1)。这是一个图灵完整的语言,你不可能处理所有的情况。当A是一个投球手时会发生什么?可能有无限数量的案例。</li><li>@ege&214;zcan它应该要么把项目放在顶部,要么放在底部,下面是我使用pastebin.com/g4dt23ju完成的实现。</li><li>@你也可以在上面添加相同的转义符(’’),它的作用也一样。在排序对象时,没有一种适合所有对象的解决方案。</li><li>这是一个很好的解决方案,但如果你比较数字,就有一个问题。请在支票前加上:<wyn>if( !isNaN(a[property]) ) a[property] = Number(a[property]); if( !isNaN(b[property]) ) b[property] = Number(b[property]);</wyn>。</li><li>这太棒了!如果只使用一个util类,那么所有的<wyn>hasOwnProperty</wyn>问题都可以避免。<wyn>Util.sortBy( People,"Name","-Surname" )</wyn>等</li></ul>[/collapse]</div><hr><P>在ES6/ES2015或更高版本中,您可以这样做:</P>[cc lang="javascript"]objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom)); |
- 这是从JS1.1开始提供的,这里的胖箭头部分是ES6/2015部分。但仍然很有用,我认为最好的答案
- @pratikkelwalkar:如果需要反转,只需切换A和B比较:objs.sort((a,b)=>b.last-nom.localecompare(a.last-nom));
- 是否可以使用索引以及地址字段进行排序:而不是使用
last_nom ,只使用数组中的数字:1 ? - @Vladbezden谢谢你的回答!此解决方案是第一个程序性工作很小、排序结果正确的解决方案,它是一个字符串数组,如:["name1"、"name10"、"name2"、"something else"、"name11"]。我得到了分类,以便与
objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom, undefined, {numberic: true})); 正确工作。
underscore.js
use underscore, its small and awesome...
sortBy_.sortBy(list, iterator, [context]) Returns a sorted copy of
list, ranked in ascending order by the results of running each value
through iterator. Iterator may also be the string name of the property
to sort by (eg. length).
1 2 3 4 5 6 7 | var objs = [ { first_nom: 'Lazslo',last_nom: 'Jamf' }, { first_nom: 'Pig', last_nom: 'Bodine' }, { first_nom: 'Pirate', last_nom: 'Prentice' } ]; var sortedObjs = _.sortBy( objs, 'first_nom' ); |
- 大卫,你能把答案改成说,以东十一〔18〕。因此,
objs 不会自行排序。函数将返回已排序的数组。这将使它更加明确。 - 反向排序:
var reverseSortedObjs = _.sortBy( objs, 'first_nom' ).reverse(); 。 - 您需要加载javascript libary"underline":
不明白为什么人们会让事情变得如此复杂:
1
2
3objs.sort(function(a, b){
return a.last_nom > b.last_nom;
});对于更严格的发动机:
1
2
3objs.sort(function(a, b){
return a.last_nom == b.last_nom ? 0 : +(a.last_nom > b.last_nom) || -1;
});交换运算符使其按逆字母顺序排序。
- 这实际上是不正确的,因为在抽签中使用的函数应该是1,0,或1,但上面的函数返回一个布尔恩。以铬为例,在幻影中的精细工作,但失败的例子。See code.google.com/p/phantomjs/issues/detail?ID=1090
- 有些发动机帐户的愚蠢,这是一种剥削。我更新了我的答案
- 我建议编辑出第一个版本I suggest editing to take out the first version.它的短暂性如此之大,以至于更具吸引力,但它不工作,至少不可信。如果有人在一个浏览器和一个工作中测试它,他们可能甚至没有发现问题(特别是如果他们没有阅读评论)。第二个版本的作品预示着第一个版本是不需要的。
- 是否有一个版本的第一个,有多个参数-特异性,然后按字母顺序排序
- @Simon I really appreciated having the"slightly wrong"version first,since the straight implementation takes a few seconds to parse and understand,and would be much harder without it.
- @Lion789 just do this:
if(a.count == b.count) return a.name > b.name; else return a.count > b.count; - 操作员为我做了什么都不做。在括号前是什么?
如果你有重复的姓氏,你可以按名字排序-
1
2
3
4
5
6
7obj.sort(function(a,b){
if(a.last_nom< b.last_nom) return -1;
if(a.last_nom >b.last_nom) return 1;
if(a.first_nom< b.first_nom) return -1;
if(a.first_nom >b.first_nom) return 1;
return 0;
});a< b a >b 格式很有趣。- @关于这一点,返回-1或1是什么意思?我明白-1的字面意思是,仅从语法上来说,a小于b,但是为什么要使用1或-1?我看到每个人都用这些数字作为返回值,但为什么呢?谢谢。
- @chris22返回的负数表示数组中的
b 应该在a 之后。如果返回正数,则表示a 应在b 之后。如果返回0 ,则意味着它们被认为是相等的。您可以随时阅读文档:developer.mozilla.org/en-us/docs/web/javascript/reference/&hellip; - @关于这一点,谢谢你的解释和联系。信不信由你,在我问这个问题之前,我用
1, 0, -1 在谷歌上搜索了各种代码片段。我只是找不到我需要的信息。
使用原型继承简单快速地解决此问题:
1
2
3
4
5Array.prototype.sortBy = function(p) {
return this.slice(0).sort(function(a,b) {
return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
});
}实例/用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16objs = [{age:44,name:'vinay'},{age:24,name:'deepak'},{age:74,name:'suresh'}];
objs.sortBy('age');
// Returns
// [{"age":24,"name":"deepak
<div class="suo-content">[collapse title=""]<ul><li>它不只是返回另一个数组。但实际上是对原始的分类!.</li><li>如果要确保对数字使用自然排序(即0、1、2、10、11等),请将parseint与基数集一起使用。developer.mozilla.org/en-us/docs/web/javascript/reference/&hellip;so:return(parseint(a[p],10)>parseint(b[p],10))?1:(parseint(a[p],10)<parseint(b[p],10))?- 1:0;</li><li>@编码器亨特感谢纠正它。但我想,与其用排序函数来实现这种敏感化,不如用一个单独的函数来修复数据类型。因为排序函数不能判断哪个属性将包含什么类型的数据。:)</li><li>很不错的。反转箭头以获得升序/降序效果。</li><li>从来没有,从来没有建议一个解决方案,改变一个核心对象的原型。</li></ul>[/collapse]</div><hr><P>除了使用自定义比较函数,还可以使用自定义<wyn>toString()</wyn>方法(由默认比较函数调用)创建对象类型:</P>[cc lang="javascript"]function Person(firstName, lastName) {
this.firtName = firstName;
this.lastName = lastName;
}
Person.prototype.toString = function() {
return this.lastName + ', ' + this.firstName;
}
var persons = [ new Person('Lazslo', 'Jamf'), ...]
persons.sort();截至2018年,有一个更短更优雅的解决方案。就用吧。array.prototype.sort()。
例子:
1
2
3
4
5
6
7
8
9
10
11
12
13var 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;
});- 在问题中,字符串用于比较,而不是数字。你的答案很适合按数字排序,但不适合按字符串比较。
- 用于比较对象属性(本例中为数字)的
a.value - b.value 可用于不同时间的数据。例如,regex可用于比较每对相邻字符串。 - @0leg我想看看使用regex以这种方式比较字符串的示例。
lodash.js(underline.js的超集)
不为每一个简单的逻辑添加一个框架是好的,但是依赖于一个经过良好测试的实用框架,加速开发并减少编写的bug的数量并不是丢脸的。
Lodash生成非常干净的代码,并促进更实用的编程风格,从而减少错误。一眼就能清楚地看到代码的意图是什么。
OP的问题可以简单地解决为:
1const sortedObjs = _.sortBy(objs, 'last_nom');更多信息?例如,我们有以下嵌套对象:
1
2
3
4
5
6const users = [
{ 'user': {'name':'fred', 'age': 48}},
{ 'user': {'name':'barney', 'age': 36 }},
{ 'user': {'name':'wilma'}},
{ 'user': {'name':'betty', 'age': 32}}
];现在,我们可以使用u.property速记
user.age 来指定应该匹配的属性的路径。我们将按嵌套的Age属性对用户对象进行排序。是的,它允许嵌套属性匹配!1const sortedObjs = _.sortBy(users, ['user.age']);要反转吗?没问题。使用逆。
1const sortedObjs = _.reverse(_.sortBy(users, ['user.age']));希望使用链接来组合两者?
1const sortedObjs = _.chain(users).sortBy('user.age').reverse().value();这里有很多好的答案,但我想指出,它们可以非常简单地扩展,以实现更复杂的排序。唯一要做的就是使用或运算符来链接类似以下的比较函数:
1objs.sort((a,b)=> fn1(a,b) || fn2(a,b) || fn3(a,b) )其中
fn1 、fn2 ……是返回[-1,0,1]的排序函数。这导致了"按fn1排序"、"按fn2排序",这与SQL中的ORDER BY差不多。此解决方案基于
|| 运算符的行为,该运算符的计算结果为第一个可转换为true的计算表达式。最简单的形式只有一个这样的内联函数:
1
2// ORDER BY last_nom
objs.sort((a,b)=> a.last_nom.localeCompare(b.last_nom) )使用
last_nom 有两个步骤,first_nom 排序顺序如下:1
2
3// ORDER_BY last_nom, first_nom
objs.sort((a,b)=> a.last_nom.localeCompare(b.last_nom) ||
a.first_nom.localeCompare(b.first_nom) )一般的比较函数可以是这样的:
1
2// ORDER BY <n>
let cmp = (a,b,n)=>a[n].localeCompare(b[n])此函数可以扩展为支持数字字段、区分大小写、任意数据类型等。
您可以使用它按排序优先级链接它们:
1
2
3
4
5
6// ORDER_BY last_nom, first_nom
objs.sort((a,b)=> cmp(a,b,"last_nom") || cmp(a,b,"first_nom") )
// ORDER_BY last_nom, first_nom DESC
objs.sort((a,b)=> cmp(a,b,"last_nom") || -cmp(a,b,"first_nom") )
// ORDER_BY last_nom DESC, first_nom DESC
objs.sort((a,b)=> -cmp(a,b,"last_nom") || -cmp(a,b,"first_nom") )这里的要点是,纯JavaScript和函数方法可以在没有外部库或复杂代码的情况下为您带来很长的路要走。它也非常有效,因为不需要进行字符串分析
你可以使用
最简单的方法:罗达什(https://lodash.com/docs/4.17.10 orderby)
此方法类似于uuSortBy,只是它允许指定要排序的迭代器的排序顺序。如果未指定顺序,则所有值都按升序排序。否则,请为降序指定"desc"的顺序,或为相应值的升序指定"asc"。
争论
集合(数组对象):要循环访问的集合。[迭代器=[.Identity]](数组[]函数[]对象[]字符串[]):要排序的迭代器。[顺序](字符串[]):迭代器的排序顺序。
退换商品
(数组):返回新排序的数组。
1
2
3
4
5
6
7
8var _ = require('lodash');
var homes = [
{"h_id":"3",
"city":"Dallas",
"state":"TX",
"zip":"75201",
"price":"162500
<hr><P>示例用法:</P>[cc lang="javascript"]objs.sort(sortBy('last_nom'));脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38/**
* @description
* Returns a function which will sort an
* array of objects by the given key.
*
* @param {String} key
* @param {Boolean} reverse
* @return {Function}
*/
const sortBy = (key, reverse) => {
// Move smaller items towards the front
// or back of the array depending on if
// we want to sort the array in reverse
// order or not.
const moveSmaller = reverse ? 1 : -1;
// Move larger items towards the front
// or back of the array depending on if
// we want to sort the array in reverse
// order or not.
const moveLarger = reverse ? -1 : 1;
/**
* @param {*} a
* @param {*} b
* @return {Number}
*/
return (a, b) => {
if (a[key] < b[key]) {
return moveSmaller;
}
if (a[key] > b[key]) {
return moveLarger;
}
return 0;
};
};- 谢谢你打破这一局面,我试着理解为什么数字化
1, 0, -1 是用来命运的。即使你的解释很好我还是不明白例如,当使用阵列长度属性时,I.E.:arr.length = -1 表示项目无法找到。我很可能在这里混淆东西,但你能帮我了解为什么数字化1, 0, -1 是用来决定秩序的吗?谢谢 - This isn't entirely accurate,but it might help to think of it like this:the function passed to array.SORTE is called once for each item in the array,as the argument named"A".每个函数呼叫的返回值是一个项目的索引(当前位置号码)如何与下一个项目的B比较。The index dicates the order of the array(0,1,2 etc)so if"a"is at index 5 and you return-1 then 5+1===4(move it near front)5+0====5(keep it where it is)etc.it walks the array comparing 2 neighbours each time until it reaches the end,leaving a sorth array.
- 谢谢你抽出时间来解释这件事。因此,使用你的解释和MDN阵列.原型.SOTE,我将告诉你我的想法:与
a 和b 相比,如果a 是比a 大得多的,Ifa 1〔EDOCX1〕〔9〕Add 1〔EDOCX1〕8〕1〕并将它放在EDOC1〔9〕EDOC1〔9〕EDOC1〕后,如果EDOC1〔1年把它放在埃多克斯前线如果a 和b 是一样的,那么就把它留在那里。 - 那声音对我好,谢谢。
我有一段适用于我的代码:
1arr.sort((a, b) => a.name > b.name)更新:不总是工作,因此不正确:(
- 它起作用,但由于某种原因,结果是不稳定的。
- 使用"-"而不是">"。那行得通。
- @不会的。你不能减去字符串。
- 应该这样做:
arr.sort((a, b) => a.name < b.name ? -1 : (a.name > b.name ? 1 : 0)) 。 - @Jean-Fran&231;OisBeauChamp,您的解决方案工作得非常好,而且更好。
我没有看到这种特别的方法建议,所以这里有一个简单的比较方法,我喜欢使用它同时适用于
string 和number :1
2
3
4
5
6
7
8
9
10
11
12const objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
const sortBy = fn => (a, b) => -(fn(a) < fn(b)) || +(fn(a) > fn(b))
const getLastName = o => o.last_nom
const sortByLastName = sortBy(getLastName)
objs.sort(sortByLastName)
console.log(objs.map(getLastName))下面是对
sortBy() 的解释:sortBy() 接受一个fn ,它从一个对象中选择要用作比较的值,并返回一个可以直接传递给Array.prototype.sort() 的函数。在本例中,我们使用o.last_nom 作为比较值,因此每当我们通过Array.prototype.sort() 接收到两个对象时,例如1{ first_nom: 'Lazslo', last_nom: 'Jamf' }和
1{ first_nom: 'Pig', last_nom: 'Bodine' }我们使用
1(a, b) => -(fn(a) < fn(b)) || +(fn(a) > fn(b))比较一下。
记住,
fn = o => o.last_nom 可以将比较函数扩展到等价的1(a, b) => -(a.last_nom < b.last_nom) || +(a.last_nom > b.last_nom)逻辑或
|| 运算符具有短路功能,在这里非常有用。因为它是如何工作的,上面的函数体意味着1
2if (a.last_nom < b.last_nom) return -1
return +(a.last_nom > b.last_nom)因此,如果
a < b 返回-1 ,否则如果a > b 返回+1 ,但如果a == b 返回a < b 和a > b 是假的,则返回+0 。作为一个额外的奖励,这里是ECMAScript 5.1中没有箭头功能的等价项,不幸的是,它没有那么简单:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
var sortBy = function (fn) {
return function (a, b) {
return -(fn(a) < fn(b)) || +(fn(a) > fn(b))
}
}
var getLastName = function (o) { return o.last_nom }
var sortByLastName = sortBy(getLastName)
objs.sort(sortByLastName)
console.log(objs.map(getLastName))我知道这个问题太老了,但我没有看到类似于我的任何实现。此版本基于Schwartzian转换习语。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29function sortByAttribute(array, ...attrs) {
// generate an array of predicate-objects contains
// property getter, and descending indicator
let predicates = attrs.map(pred => {
let descending = pred.charAt(0) === '-' ? -1 : 1;
pred = pred.replace(/^-/, '');
return {
getter: o => o[pred],
descend: descending
};
});
// schwartzian transform idiom implementation. aka:"decorate-sort-undecorate"
return array.map(item => {
return {
src: item,
compareValues: predicates.map(predicate => predicate.getter(item))
};
})
.sort((o1, o2) => {
let i = -1, result = 0;
while (++i < predicates.length) {
if (o1.compareValues[i] < o2.compareValues[i]) result = -1;
if (o1.compareValues[i] > o2.compareValues[i]) result = 1;
if (result *= predicates[i].descend) break;
}
return result;
})
.map(item => item.src);
}下面是一个如何使用它的示例:
1
2
3
4
5
6
7
8
9
10
11let games = [
{ name: 'Pako', rating: 4.21 },
{ name: 'Hill Climb Racing', rating: 3.88 },
{ name: 'Angry Birds Space', rating: 3.88 },
{ name: 'Badland', rating: 4.33 }
];
// sort by one attribute
console.log(sortByAttribute(games, 'name'));
// sort by mupltiple attributes
console.log(sortByAttribute(games, '-rating', 'name'));
排序(更多)复杂的对象数组因为您可能会遇到更复杂的数据结构,比如这个数组,所以我将展开解决方案。
DRAre more pluggable version based on @ege-?zcan's very lovely answer.
问题
我遇到下面的问题,无法更改。我也不想暂时弄平物体。我也不想使用underline/lodash,主要是出于性能原因和自己实现它的乐趣。
1
2
3
4
5var People = [
{Name: {name:"Name", surname:"Surname
<div class="suo-content">[collapse title=""]<ul><li>为什么?This is not the answer to original question and"the goal"could be solved simply with people.sort((a,b)={}{return a.name.name.name.localecompare(B.name.name) 124;A.name.surname.locampare(B.name.surname.surname)})</li></ul>[/collapse]</div><hr><P>一个简单的方法:</P>[cc lang="javascript"]objs.sort(function(a,b) {
return b.last_nom.toLowerCase() < a.last_nom.toLowerCase();
});注意,
'.toLowerCase()' 是防止错误发生的必要条件。在比较字符串时。- 您可以使用arrow函数让代码更加优雅:
objs.sort( (a,b) => b.last_nom.toLowerCase() < a.last_nom.toLowerCase() ); 。 - 这是错误的,原因与这里解释的相同。
- 箭头函数不适合ES5。吨级发动机仍限制在ES5。在我的例子中,我发现上面的答案明显更好,因为我使用的是ES5引擎(我的公司强制使用)。
还有一个选择:
1
2
3
4
5
6
7
8
9
10
11var someArray = [...];
function generateSortFn(prop, reverse) {
return function (a, b) {
if (a[prop] < b[prop]) return reverse ? 1 : -1;
if (a[prop] > b[prop]) return reverse ? -1 : 1;
return 0;
};
}
someArray.sort(generateSortFn('name', true));默认情况下按升序排序。
- 这个解决方案可以产生干净的代码。工作很好。
- 如果需要,这里提供了用于按多个字段排序的略微更改版本:stackoverflow.com/questions/6913512/&hellip;
additional desc params for Ege ?zcan code
1
2
3
4
5
6
7
8
9
10function dynamicSort(property, desc) {
if (desc) {
return function (a, b) {
return (a[property] > b[property]) ? -1 : (a[property] < b[property]) ? 1 : 0;
}
}
return function (a, b) {
return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
}
}结合ege的动态解决方案和vinay的想法,您可以得到一个很好的强大解决方案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26Array.prototype.sortBy = function() {
function _sortByAttr(attr) {
var sortOrder = 1;
if (attr[0] =="-") {
sortOrder = -1;
attr = attr.substr(1);
}
return function(a, b) {
var result = (a[attr] < b[attr]) ? -1 : (a[attr] > b[attr]) ? 1 : 0;
return result * sortOrder;
}
}
function _getSortFunc() {
if (arguments.length == 0) {
throw"Zero length arguments not allowed for Array.sortBy()";
}
var args = arguments;
return function(a, b) {
for (var result = 0, i = 0; result == 0 && i < args.length; i++) {
result = _sortByAttr(args[i])(a, b);
}
return result;
}
}
return this.sort(_getSortFunc.apply(null, arguments));
}用途:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34// Utility for printing objects
Array.prototype.print = function(title) {
console.log("************************************************************************");
console.log("****"+title);
console.log("************************************************************************");
for (var i = 0; i < this.length; i++) {
console.log("Name:"+this[i].FirstName, this[i].LastName,"Age:"+this[i].Age);
}
}
// Setup sample data
var arrObj = [
{FirstName:"Zach", LastName:"Emergency", Age: 35},
{FirstName:"Nancy", LastName:"Nurse", Age: 27},
{FirstName:"Ethel", LastName:"Emergency", Age: 42},
{FirstName:"Nina", LastName:"Nurse", Age: 48},
{FirstName:"Anthony", LastName:"Emergency", Age: 44},
{FirstName:"Nina", LastName:"Nurse", Age: 32},
{FirstName:"Ed", LastName:"Emergency", Age: 28},
{FirstName:"Peter", LastName:"Physician", Age: 58},
{FirstName:"Al", LastName:"Emergency", Age: 51},
{FirstName:"Ruth", LastName:"Registration", Age: 62},
{FirstName:"Ed", LastName:"Emergency", Age: 38},
{FirstName:"Tammy", LastName:"Triage", Age: 29},
{FirstName:"Alan", LastName:"Emergency", Age: 60},
{FirstName:"Nina", LastName:"Nurse", Age: 54}
];
//Unit Tests
arrObj.sortBy("LastName").print("LastName Ascending");
arrObj.sortBy("-LastName").print("LastName Descending");
arrObj.sortBy("LastName","FirstName","-Age").print("LastName Ascending, FirstName Ascending, Age Descending");
arrObj.sortBy("-FirstName","Age").print("FirstName Descending, Age Ascending");
arrObj.sortBy("-Age").print("Age Descending");- 谢谢你的主意!以这种方式,请不要鼓励人们改变阵列原型(见我的例子末尾的警告)。
根据示例,需要按两个字段(姓氏、名字)排序,而不是按一个字段排序。可以使用ALASQL库在一行中进行此排序:
1var res = alasql('SELECT * FROM ? ORDER BY last_nom, first_nom',[objs]);在JSfiddle中尝试这个例子。
按属性对对象数组排序的简单函数
1
2
3
4
5
6
7
8
9
10
11
12
13function sortArray(array, property, direction) {
direction = direction || 1;
array.sort(function compare(a, b) {
let comparison = 0;
if (a[property] > b[property]) {
comparison = 1 * direction;
} else if (a[property] < b[property]) {
comparison = -1 * direction;
}
return comparison;
});
return array; // Chainable
}用途:
1
2
3
4
5
6
7
8var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
sortArray(objs,"last_nom"); // Asc
sortArray(objs,"last_nom", -1); // Desc
1objs.sort(function(a,b){return b.last_nom>a.last_nom})- 实际上,它似乎不起作用,必须使用公认的答案。排序不正确。
为了避免混淆,您可能需要将它们转换为小写。
1
2
3
4
5
6
7
8
9
10
11objs.sort(function (a,b) {
var nameA=a.last_nom.toLowerCase(), nameB=b.last_nom.toLowerCase()
if (nameA < nameB)
return -1;
if (nameA > nameB)
return 1;
return 0; //no sorting
})
1
2
3
4
5
6
7
8
9
10
11function compare(propName) {
return function(a,b) {
if (a[propName] < b[propName])
return -1;
if (a[propName] > b[propName])
return 1;
return 0;
};
}
objs.sort(compare("last_nom"));- 请考虑编辑您的邮件,以便进一步澄清您的代码是什么,以及它为什么会解决问题。一个答案是,大多数都包含了代码(即使是在工作中),通常会有助于OP了解他们的问题。
给出了原始示例:
1
2
3
4
5var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];按多个字段排序:
1
2
3
4
5objs.sort(function(left, right) {
var last_nom_order = left.last_nom.localeCompare(right.last_nom);
var first_nom_order = left.first_nom.localeCompare(right.first_nom);
return last_nom_order || first_nom_order;
});笔记
- 如果
a、 a==b 、a>b 分别支持a.localeCompare(b) 并返回-1,0,1。 - 最后一行中的
|| 给予last_nom 比first_nom 优先权。 - 数字字段的减法运算:
var age_order = left.age - right.age; 。 - 相反顺序,
return -last_nom_order || -first_nom_order || -age_order; 。
使用RAMDA,
NPM安装Ramda
1
2
3
4
5
6
7
8import R from 'ramda'
var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
var ascendingSortedObjs = R.sortBy(R.prop('last_nom'), objs)
var descendingSortedObjs = R.reverse(ascendingSortedObjs)这是一个简单的问题,不知道为什么人们有如此复杂的解决方案。一个简单的排序函数(基于快速排序算法):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28function sortObjectsArray(objectsArray, sortKey)
{
// Quick Sort:
var retVal;
if (1 < objectsArray.length)
{
var pivotIndex = Math.floor((objectsArray.length - 1) / 2); // middle index
var pivotItem = objectsArray[pivotIndex]; // value in the middle index
var less = [], more = [];
objectsArray.splice(pivotIndex, 1); // remove the item in the pivot position
objectsArray.forEach(function(value, index, array)
{
value[sortKey] <= pivotItem[sortKey] ? // compare the 'sortKey' proiperty
less.push(value) :
more.push(value) ;
});
retVal = sortObjectsArray(less, sortKey).concat([pivotItem], sortObjectsArray(more, sortKey));
}
else
{
retVal = objectsArray;
}
return retVal;
}使用实例:
1
2
3
4
5
6
7var myArr =
[
{ val: 'x', idx: 3 },
{ val: 'y', idx: 2 },
{ val: 'z', idx: 5 },
];
myArr = sortObjectsArray(myArr, 'idx');- 一个简单的解决办法是什么?简单的算法,但不是简单的解决办法。
- 这很简单,因为它没有使用任何外部图书馆,也没有改变物体的原型。在我看来,守则的长度对守则的复杂性没有直接影响
- 好吧,让我用不同的词来试试:如何使轮胎成为一个简单的解决方案?
使用xprototype:https://github.com/reduardo7/xprototype/blob/master/readme.md sortbycol1-col2-coln
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27var o = [
{ Name: 'Lazslo', LastName: 'Jamf' },
{ Name: 'Pig', LastName: 'Bodine' },
{ Name: 'Pirate', LastName: 'Prentice' },
{ Name: 'Pag', LastName: 'Bodine' }
];
// Original
o.each(function (a, b) { console.log(a, b); });
/*
0 Object {Name:"Lazslo", LastName:"Jamf
<hr>
<p>
I Just enhanced Ege ?zcan's dynamic sort to dive deep inside objects.
If Data looks like this:
</p>
[cc lang="javascript"]obj = [
{
a: { a: 1, b: 2, c: 3 },
b: { a: 4, b: 5, c: 6 }
},
{
a: { a: 3, b: 2, c: 1 },
b: { a: 6, b: 5, c: 4 }
}];如果你想对A.A属性进行分类,我认为我的增强功能很有帮助。我向如下对象添加了新功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14Object.defineProperty(Object.prototype, 'deepVal', {
enumerable: false,
writable: true,
value: function (propertyChain) {
var levels = propertyChain.split('.');
parent = this;
for (var i = 0; i < levels.length; i++) {
if (!parent[levels[i]])
return undefined;
parent = parent[levels[i]];
}
return parent;
}
});并更改了动态端口的返回函数:
1
2
3
4return function (a,b) {
var result = ((a.deepVal(property) > b.deepVal(property)) - (a.deepVal(property) < b.deepVal(property)));
return result * sortOrder;
}现在你可以通过A.A.的方式进行排序:
1obj.sortBy('a.a');参见jsfiddle中的commplete脚本
方式1:
您可以使用
Underscore.js 。首先导入下划线。1
2import * as _ from 'underscore';
let SortedObjs = _.sortBy(objs, 'last_nom');方法二:使用比较函数。
1
2
3
4
5
6
7
8
9function compare(first, second) {
if (first.last_nom < second.last_nom)
return -1;
if (first.last_nom > second.last_nom)
return 1;
return 0;
}
objs.sort(compare);使用罗达什或下划线,这是一块蛋糕
1> const sortedList = _.orderBy(objs, [last_nom], [asc]); // asc or desc
It works for me. Here It will keep undefined to the end.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39function sort(items, property, direction) {
function compare(a, b) {
if(!a[property] && !b[property]) {
return 0;
} else if(a[property] && !b[property]) {
return -1;
} else if(!a[property] && b[property]) {
return 1;
} else {
const value1 = a[property].toString().toUpperCase(); // ignore upper and lowercase
const value2 = b[property].toString().toUpperCase(); // ignore upper and lowercase
if (value1 < value2) {
return direction === 0 ? -1 : 1;
} else if (value1 > value2) {
return direction === 0 ? 1 : -1;
} else {
return 0;
}
}
}
return items.sort(compare);
}
var items = [
{ name: 'Edward', value: 21 },
{ name: 'Sharpe', value: 37 },
{ name: 'And', value: 45 },
{ name: 'The', value: -12 },
{ name: undefined, value: -12 },
{ name: 'Magnetic', value: 13 },
{ name: 'Zeros', value: 37 }
];
console.log('Ascending Order:- ');
console.log(sort(items, 'name', 0));
console.log('Decending Order:- ');
console.log(sort(items, 'name', 1));
This will sort a two level nested array by the property passed to it in alpha numeric order.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function sortArrayObjectsByPropAlphaNum(property) {
return function (a,b) {
var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
var aA = a[property].replace(reA, '');
var bA = b[property].replace(reA, '');
if(aA === bA) {
var aN = parseInt(a[property].replace(reN, ''), 10);
var bN = parseInt(b[property].replace(reN, ''), 10);
return aN === bN ? 0 : aN > bN ? 1 : -1;
} else {
return a[property] > b[property] ? 1 : -1;
}
};
}用途:
1objs.sort(utils.sortArrayObjectsByPropAlphaNum('last_nom'));我遇到了排序对象数组的问题,改变了值的优先级,基本上我想按年龄对数组中的人进行排序,然后按姓或仅按姓、名进行排序。我认为与其他答案相比,这是最简单的解决方案。
它用于调用SortPeoples(['array'、'of'、'properties'],reverse=false)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45///////////////////////example array of peoples ///////////////////////
var peoples = [
{name:"Zach", surname:"Emergency", age: 1},
{name:"Nancy", surname:"Nurse", age: 1},
{name:"Ethel", surname:"Emergency", age: 1},
{name:"Nina", surname:"Nurse", age: 42},
{name:"Anthony", surname:"Emergency", age: 42},
{name:"Nina", surname:"Nurse", age: 32},
{name:"Ed", surname:"Emergency", age: 28},
{name:"Peter", surname:"Physician", age: 58},
{name:"Al", surname:"Emergency", age: 58},
{name:"Ruth", surname:"Registration", age: 62},
{name:"Ed", surname:"Emergency", age: 38},
{name:"Tammy", surname:"Triage", age: 29},
{name:"Alan", surname:"Emergency", age: 60},
{name:"Nina", surname:"Nurse", age: 58}
];
//////////////////////// Sorting function /////////////////////
function sortPeoples(propertyArr, reverse) {
function compare(a,b) {
var i=0;
while (propertyArr[i]) {
if (a[propertyArr[i]] < b[propertyArr[i]]) return -1;
if (a[propertyArr[i]] > b[propertyArr[i]]) return 1;
i++;
}
return 0;
}
peoples.sort(compare);
if (reverse){
peoples.reverse();
}
};
////////////////end of sorting method///////////////
function printPeoples(){
$('#output').html('');
peoples.forEach( function(person){
$('#output').append(person.surname+""+person.name+""+person.age+"");
} )
}1
2
3
4
5
6
7
8
9
10
11
12
13<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</head>
<html>
<body>
<button onclick="sortPeoples(['surname']); printPeoples()">sort by ONLY by surname ASC results in mess with same name cases</button>
<button onclick="sortPeoples(['surname', 'name'], true); printPeoples()">sort by surname then name DESC</button>
<button onclick="sortPeoples(['age']); printPeoples()">sort by AGE ASC. Same issue as in first case</button>
<button onclick="sortPeoples(['age', 'surname']); printPeoples()">sort by AGE and Surname ASC. Adding second field fixed it.</button>
</body>
</html>- 人群:(
因此,这里有一个排序算法,它可以在任何类型的对象的数组中按任意顺序排序,而不受数据类型比较(即数字、字符串)的限制。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28function smoothSort(items,prop,reverse) {
var length = items.length;
for (var i = (length - 1); i >= 0; i--) {
//Number of passes
for (var j = (length - i); j > 0; j--) {
//Compare the adjacent positions
if(reverse){
if (items[j][prop] > items[j - 1][prop]) {
//Swap the numbers
var tmp = items[j];
items[j] = items[j - 1];
items[j - 1] = tmp;
}
}
if(!reverse){
if (items[j][prop] < items[j - 1][prop]) {
//Swap the numbers
var tmp = items[j];
items[j] = items[j - 1];
items[j - 1] = tmp;
}
}
}
}
return items;
}第一个参数项是对象数组,
prop是要排序的对象的键,
Reverse是一个布尔参数,如果为true,则按升序返回;如果为false,则按降序返回。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31// Sort Array of Objects
// Data
var booksArray = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
// Property to Sort By
var args ="last_nom";
// Function to Sort the Data by given Property
function sortByProperty(property) {
return function (a, b) {
var sortStatus = 0,
aProp = a[property].toLowerCase(),
bProp = b[property].toLowerCase();
if (aProp < bProp) {
sortStatus = -1;
} else if (aProp > bProp) {
sortStatus = 1;
}
return sortStatus;
};
}
// Implementation
var sortedArray = booksArray.sort(sortByProperty(args));
console.log("sortedArray:" + JSON.stringify(sortedArray) );控制台日志输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31"sortedArray:
[{"first_nom":"Pig","last_nom":"Bodine
<hr><P>我会给你一个实现selectionsort算法的解决方案,它简单有效</P>[cc lang="javascript"]var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
function selection_Sort(num) {
//console.log(num);
var temp, index;
for (var i = 0; i <= num.length - 1; i++) {
index = i;
for (var j = i + 1; j <= num.length - 1; j++) {
// you can use first_nom/last_nom,any way you choose to sort
if (num[j]. last_nom < num[index]. last_nom) {
index = j;
}
}
//below is the swapping part
temp = num[i]. last_nom;
num[i]. last_nom = num[index]. last_nom;
num[index]. last_nom = temp;
};
console.log(num);
return num;
}
selection_Sort(objs);很高兴看到这么好的答案
In case you have nested objects
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26const objs = [{
first_nom: 'Lazslo',
last_nom: 'Jamf',
moreDetails: {
age: 20
}
}, {
first_nom: 'Pig',
last_nom: 'Bodine',
moreDetails: {
age: 21
}
}, {
first_nom: 'Pirate',
last_nom: 'Prentice',
moreDetails: {
age: 22
}
}];
nestedSort = (prop1, prop2 = null, direction = 'asc') => (e1, e2) => {
const a = prop2 ? e1[prop1][prop2] : e1[prop1],
b = prop2 ? e2[prop1][prop2] : e2[prop1],
sortOrder = direction ==="asc" ? 1 : -1
return (a < b) ? -sortOrder : (a > b) ? sortOrder : 0;
}像这样称呼它
1
2
3
4objs.sort(nestedSort("last_nom"));
objs.sort(nestedSort("last_nom", null,"desc"));
objs.sort(nestedSort("moreDetails","age"));
objs.sort(nestedSort("moreDetails","age","desc"));
- 关于jquery:如何对对象的javascript数组进行数字排序,然后按字母顺序排序?
- 关于javascript:如何基于打字稿中的键对对象数组进行排序
- 关于javascript:按自定义顺序排序
- 关于javascript:在Angular 6中按对象字段排序数组
- javascript按字符串属性对对象数组排序
- javascript:如何按照其中一个字段中的值对记录数组进行排序?
- 关于Javascript:按索引排序数组
- 按特定键值对对象数组进行排序javascript
- 关于javascript:排序JSON列表?
- 关于排序:javascript排序,结果排序等于。怎样?
- 如何从javascript对象中删除属性?
- JavaScript如何检查数组是否包含对象?
- python:如何按值对字典进行排序?
- 按属性对javascript对象数组排序
- 关于javascript:如何正确排序整数数组
- 如何检查JavaScript中的字符串是否包含子字符串?
- 关于javascript:在HTML5本地存储中存储对象
- 关于javascript:如何检查对象是否是数组?
- 如何从javascript中的数组中删除特定元素?
- 在javascript中For-each 数组