sortingJavaScript对象的数组
我使用Ajax读取下列对象,并将它们存储在一个数组中:
var homes = [ { "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": "162500" }, { "h_id": "4", "city": "Bevery Hills", "state": "CA", "zip": "90210", "price": "319250" }, { "h_id": "5", "city": "New York", "state": "NY", "zip": "00010", "price": "962500" } ];
如何创build一个函数按price
属性按升序 或 降序sorting对象只使用JavaScript?
按房价按升序sorting
homes.sort(function(a, b) { return parseFloat(a.price) - parseFloat(b.price); });
有些文档可以在这里find。
这是一个更灵活的版本,它允许您创build可重用的sortingfunction,并按任何字段进行sorting。
var sort_by = function(field, reverse, primer){ var key = primer ? function(x) {return primer(x[field])} : function(x) {return x[field]}; reverse = !reverse ? 1 : -1; return function (a, b) { return a = key(a), b = key(b), reverse * ((a > b) - (b > a)); } }
现在你可以按任意字段sorting
var homes = [{ "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": "162500" }, { "h_id": "4", "city": "Bevery Hills", "state": "CA", "zip": "90210", "price": "319250" }, { "h_id": "5", "city": "New York", "state": "NY", "zip": "00010", "price": "962500" }]; // Sort by price high to low homes.sort(sort_by('price', true, parseInt)); // Sort by city, case-insensitive, AZ homes.sort(sort_by('city', false, function(a){return a.toUpperCase()}));
要对其进行sorting,您需要创build一个带有两个参数的比较函数。 然后使用该比较函数调用sort函数,如下所示:
// a and b are object elements of your array function mycomparator(a,b) { return parseInt(a.price, 10) - parseInt(b.price, 10); } homes.sort(mycomparator);
如果要按升序切换减号每一侧的expression式。
如果有人需要它进行string分类,
var dataArr = { "hello": [{ "id": 114, "keyword": "zzzzzz", "region": "Sri Lanka", "supportGroup": "administrators", "category": "Category2" }, { "id": 115, "keyword": "aaaaa", "region": "Japan", "supportGroup": "developers", "category": "Category2" }] }; var sortArray = dataArr['hello']; sortArray.sort(function(a,b) { if ( a.region < b.region ) return -1; if ( a.region > b.region ) return 1; return 0; } );
你想要在JavaScript中sorting,对不对? 你想要的是sort()
函数 。 在这种情况下,您需要编写一个比较函数并将其传递给sort()
,如下所示:
function comparator(a, b) { return parseInt(a["price"], 10) - parseInt(b["price"], 10); } var json = { "homes": [ /* your previous data */ ] }; console.log(json["homes"].sort(comparator));
你的比较器将数组中的每一个嵌套散列之一,并通过检查“价格”字段来决定哪一个更高。
如果你有一个ES6兼容的浏览器,你可以使用:
- 箭头function
- Number()函数
- sort()函数
升序和降序sorting顺序的差异是比较函数返回值的符号:
var ascending = homes.sort((a, b) => Number(a.price) - Number(b.price)); var descending = homes.sort((a, b) => Number(b.price) - Number(a.price));
这是一个工作代码片段:
var homes = [{ "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": "162500" }, { "h_id": "4", "city": "Bevery Hills", "state": "CA", "zip": "90210", "price": "319250" }, { "h_id": "5", "city": "New York", "state": "NY", "zip": "00010", "price": "962500" }]; var ascending = homes.sort((a, b) => Number(a.price) - Number(b.price)); var descending = homes.sort((a, b) => Number(b.price) - Number(a.price)); console.log("ascending", ascending); console.log("descending", descending);
由于这个答案以前是upvoted,我会保留原来的答案,但我强烈build议sortBy
sorting一个数组,并允许多种sorting标准 (通过Schwartzian变换 ) 的新实现 请参阅这个要点:sortBy.js
创buildsortingfunction
var sortBy = (function () { const _defaults = { parser: (x) => x, desc: false }; const isObject = (o) => o !== null && typeof o === "object"; const isDefined = (v) => typeof v !== "undefined"; //gets the item to be sorted function getItem (x) { const isProp = isObject(x) && isDefined(x[this.prop]); return this.parser(isProp ? x[this.prop] : x); } /** * Sorts an array of elements * @param {Array} array: the collection to sort * @param {Object} options: * options with the sort rules. It have the properties: * - {String} prop: property name (if it is an Array of objects) * - {Boolean} desc: determines whether the sort is descending * - {Function} parser: function to parse the items to expected type * @return {Array} */ return function (array, options) { if (!(array instanceof Array) || !array.length) return []; const opt = Object.assign({}, _defaults, options); opt.desc = opt.desc ? -1 : 1; return array.sort(function (a, b) { a = getItem.call(opt, a); b = getItem.call(opt, b); return opt.desc * (a < b ? -1 : +(a > b)); }); }; }());
设置未分类的数据
var data = [ {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90, tip: 0, type: "tab"}, {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90, tip: 0, type: "tab"}, {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"}, {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90, tip: 0, type: "tab"}, {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90, tip: 0, type: "tab"}, {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0, type: "cash"}, {date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}, {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90, tip: 0, type: "tab"}, {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"}, {date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"}, {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90, tip: 0, type: "tab"}, {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash"} ];
使用它
排列数组,由"date"
作为String
//sort by @date (ascending) sortBy(data, { prop: "date" }); // first element expected { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" } // last element expected { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}
如果您想忽略区分大小写,请设置parser
callback:
//sort by @type (ascending) sortBy(data, { prop: "type", // ignore case sensitive parser: (t) => t.toUpperCase() }); // first element expected { date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash" } // last element expected { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa" }
如果要将"date"
字段转换为Date
types:
//sort by @date (descending) sortBy([].concat(data), { prop: "date", desc: true, parser: (d) => new Date(d) }); // first element expected { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"} // last element expected { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }
感谢@Ozesh的反馈,与虚假值相关的问题是固定的。
使用lodash.sortBy ,(使用commonjs的指令,你也可以把脚本的include-tag放在你的html的顶部)
var sortBy = require('lodash.sortby'); // or sortBy = require('lodash').sortBy;
降序
var descendingOrder = sortBy( homes, 'price' ).reverse();
升序
var ascendingOrder = sortBy( homes, 'price' );
这是一个很好的JQuery插件:
http://plugins.jquery.com/project/sort(Wayback Machine Link)
您可以使用带有callback函数的JavaScript sort
方法:
function compareASC(homeA, homeB) { return parseFloat(homeA.price) - parseFloat(homeB.price); } function compareDESC(homeA, homeB) { return parseFloat(homeB.price) - parseFloat(homeA.price); } // Sort ASC homes.sort(compareASC); // Sort DESC homes.sort(compareDESC);
以上是所有答案的顶点。
小提琴validation: http : //jsfiddle.net/bobberino/4qqk3/
var sortOn = function (arr, prop, reverse, numeric) { // Ensure there's a property if (!prop || !arr) { return arr } // Set up sort function var sort_by = function (field, rev, primer) { // Return the required a,b function return function (a, b) { // Reset a, b to the field a = primer(a[field]), b = primer(b[field]); // Do actual sorting, reverse as needed return ((a < b) ? -1 : ((a > b) ? 1 : 0)) * (rev ? -1 : 1); } } // Distinguish between numeric and string to prevent 100's from coming before smaller // eg // 1 // 20 // 3 // 4000 // 50 if (numeric) { // Do sort "in place" with sort_by function arr.sort(sort_by(prop, reverse, function (a) { // - Force value to a string. // - Replace any non numeric characters. // - Parse as float to allow 0.02 values. return parseFloat(String(a).replace(/[^0-9.-]+/g, '')); })); } else { // Do sort "in place" with sort_by function arr.sort(sort_by(prop, reverse, function (a) { // - Force value to string. return String(a).toUpperCase(); })); } }
我也曾与某种评级和多个领域的sorting:
arr = [ {type:'C', note:834}, {type:'D', note:732}, {type:'D', note:008}, {type:'F', note:474}, {type:'P', note:283}, {type:'P', note:165}, {type:'X', note:173}, {type:'Z', note:239}, ]; arr.sort(function(a,b){ var _a = ((a.type==='C')?'0':(a.type==='P')?'1':'2'); _a += (a.type.localeCompare(b.type)===-1)?'0':'1'; _a += (a.note>b.note)?'1':'0'; var _b = ((b.type==='C')?'0':(b.type==='P')?'1':'2'); _b += (b.type.localeCompare(a.type)===-1)?'0':'1'; _b += (b.note>a.note)?'1':'0'; return parseInt(_a) - parseInt(_b); });
结果
[ {"type":"C","note":834}, {"type":"P","note":165}, {"type":"P","note":283}, {"type":"D","note":8}, {"type":"D","note":732}, {"type":"F","note":474}, {"type":"X","note":173}, {"type":"Z","note":239} ]
如果您使用Underscore.js,请尝试sortBy:
// price is of an integer type _.sortBy(homes, "price"); // price is of a string type _.sortBy(homes, function(home) {return parseInt(home.price);});
为了sorting数组,你必须定义一个比较函数。 这个函数在你想要的sorting模式或顺序上(即上升或下降)总是不同的。
让我们创build一些函数对数组进行升序或降序sorting,其中包含对象,string或数值。
function sorterAscending(a,b) { return ab; } function sorterDescending(a,b) { return ba; } function sorterPriceAsc(a,b) { return parseInt(a['price']) - parseInt(b['price']); } function sorterPriceDes(a,b) { return parseInt(b['price']) - parseInt(b['price']); }
对数字进行sorting(按字母顺序和升序排列):
var fruits = ["Banana", "Orange", "Apple", "Mango"]; fruits.sort();
对数字进行sorting(按字母顺序和降序):
var fruits = ["Banana", "Orange", "Apple", "Mango"]; fruits.sort(); fruits.reverse();
对数字进行sorting(数字和升序):
var points = [40,100,1,5,25,10]; points.sort(sorterAscending());
对数字进行sorting(数字和降序):
var points = [40,100,1,5,25,10]; points.sort(sorterDescending());
如上所述使用sorterPriceAsc和sorterPriceDes方法与您的数组与期望的关键。
homes.sort(sorterPriceAsc()) or homes.sort(sorterPriceDes())
尽pipe对单个数组进行sorting有点矫枉过正,但是这个原型函数允许使用dot
语法按任意键(升序或降序)sortingJavascript数组, 包括嵌套键 。
(function(){ var keyPaths = []; var saveKeyPath = function(path) { keyPaths.push({ sign: (path[0] === '+' || path[0] === '-')? parseInt(path.shift()+1) : 1, path: path }); }; var valueOf = function(object, path) { var ptr = object; for (var i=0,l=path.length; i<l; i++) ptr = ptr[path[i]]; return ptr; }; var comparer = function(a, b) { for (var i = 0, l = keyPaths.length; i < l; i++) { aVal = valueOf(a, keyPaths[i].path); bVal = valueOf(b, keyPaths[i].path); if (aVal > bVal) return keyPaths[i].sign; if (aVal < bVal) return -keyPaths[i].sign; } return 0; }; Array.prototype.sortBy = function() { keyPaths = []; for (var i=0,l=arguments.length; i<l; i++) { switch (typeof(arguments[i])) { case "object": saveKeyPath(arguments[i]); break; case "string": saveKeyPath(arguments[i].match(/[+-]|[^.]+/g)); break; } } return this.sort(comparer); }; })();
用法:
var data = [ { name: { first: 'Josh', last: 'Jones' }, age: 30 }, { name: { first: 'Carlos', last: 'Jacques' }, age: 19 }, { name: { first: 'Carlos', last: 'Dante' }, age: 23 }, { name: { first: 'Tim', last: 'Marley' }, age: 9 }, { name: { first: 'Courtney', last: 'Smith' }, age: 27 }, { name: { first: 'Bob', last: 'Smith' }, age: 30 } ] data.sortBy('age'); // "Tim Marley(9)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Bob Smith(30)"
使用点语法或数组语法对嵌套属性进行sorting:
data.sortBy('name.first'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)" data.sortBy(['name', 'first']); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
按多个键sorting:
data.sortBy('name.first', 'age'); // "Bob Smith(30)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)" data.sortBy('name.first', '-age'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
你可以分叉回购: https : //github.com/eneko/Array.sortBy
这可以通过简单的一行valueof()sorting函数来实现。 运行下面的代码片段来查看演示。
var homes = [ { "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": "162500" }, { "h_id": "4", "city": "Bevery Hills", "state": "CA", "zip": "90210", "price": "319250" }, { "h_id": "5", "city": "New York", "state": "NY", "zip": "00010", "price": "962500" } ]; console.log("To sort descending/highest first, use operator '<'"); homes.sort(function(a,b) { return a.price.valueOf() < b.price.valueOf();}); console.log(homes); console.log("To sort ascending/lowest first, use operator '>'"); homes.sort(function(a,b) { return a.price.valueOf() > b.price.valueOf();}); console.log(homes);
使用ECMAScript 6 StoBor的答案可以做得更加简洁:
homes.sort((a, b) => a.price - b.price)
下面是一本书“JavaScript:The Good Parts”中的一个稍作修改的优雅实现版本。
注意 :这个版本是稳定的 。 它在执行下一个链接sorting时保留第一个sorting的顺序。
我已经添加了isAscending
参数。 ES6
其转换为ES6
标准和作者推荐的“较新”的好的部分。
您可以按升序sorting,也可以按降序sorting和按多个属性进行sorting。
const by = function (name, minor, isAscending=true) { const reverseMutliplier = isAscending ? 1 : -1; return function (o, p) { let a, b; let result; if (o && p && typeof o === "object" && typeof p === "object") { a = o[name]; b = p[name]; if (a === b) { return typeof minor === 'function' ? minor(o, p) : 0; } if (typeof a === typeof b) { result = a < b ? -1 : 1; } else { result = typeof a < typeof b ? -1 : 1; } return result * reverseMutliplier; } else { throw { name: "Error", message: "Expected an object when sorting by " + name }; } }; }; let s = [ {first: 'Joe', last: 'Besser'}, {first: 'Moe', last: 'Howard'}, {first: 'Joe', last: 'DeRita'}, {first: 'Shemp', last: 'Howard'}, {first: 'Larry', last: 'Fine'}, {first: 'Curly', last: 'Howard'} ]; // Sort by: first ascending, last ascending s.sort(by("first", by("last"))); console.log("Sort by: first ascending, last ascending: ", s); // "[ // {"first":"Curly","last":"Howard"}, // {"first":"Joe","last":"Besser"}, <====== // {"first":"Joe","last":"DeRita"}, <====== // {"first":"Larry","last":"Fine"}, // {"first":"Moe","last":"Howard"}, // {"first":"Shemp","last":"Howard"} // ] // Sort by: first ascending, last descending s.sort(by("first", by("last", 0, false))); console.log("sort by: first ascending, last descending: ", s); // "[ // {"first":"Curly","last":"Howard"}, // {"first":"Joe","last":"DeRita"}, <======== // {"first":"Joe","last":"Besser"}, <======== // {"first":"Larry","last":"Fine"}, // {"first":"Moe","last":"Howard"}, // {"first":"Shemp","last":"Howard"} // ]
我最近写了一个通用函数来pipe理这个,如果你想使用它。
/** * Sorts an object into an order * * @require jQuery * * @param object Our JSON object to sort * @param type Only alphabetical at the moment * @param identifier The array or object key to sort by * @param order Ascending or Descending * * @returns Array */ function sortItems(object, type, identifier, order){ var returnedArray = []; var emptiesArray = []; // An array for all of our empty cans // Convert the given object to an array $.each(object, function(key, object){ // Store all of our empty cans in their own array // Store all other objects in our returned array object[identifier] == null ? emptiesArray.push(object) : returnedArray.push(object); }); // Sort the array based on the type given switch(type){ case 'alphabetical': returnedArray.sort(function(a, b){ return(a[identifier] == b[identifier]) ? 0 : ( // Sort ascending or descending based on order given order == 'asc' ? a[identifier] > b[identifier] : a[identifier] < b[identifier] ) ? 1 : -1; }); break; default: } // Return our sorted array along with the empties at the bottom depending on sort order return order == 'asc' ? returnedArray.concat(emptiesArray) : emptiesArray.concat(returnedArray); }
homes.sort(function(a, b){ var nameA=a.prices.toLowerCase(), nameB=b.prices.toLowerCase() if (nameA < nameB) //sort string ascending return -1 if (nameA > nameB) return 1 return 0 //default return value (no sorting) })
嗨阅读这篇文章后,我做了一个sortComparator为我的需要,与比较多个json属性的function,我想与你分享。
这个解决scheme只比较string的升序,但解决scheme可以很容易地扩展为每个属性支持:逆序sorting,其他数据types,使用语言环境,铸造等
var homes = [{ "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": "162500" }, { "h_id": "4", "city": "Bevery Hills", "state": "CA", "zip": "90210", "price": "319250" }, { "h_id": "5", "city": "New York", "state": "NY", "zip": "00010", "price": "962500" }]; // comp = array of attributes to sort // comp = ['attr1', 'attr2', 'attr3', ...] function sortComparator(a, b, comp) { // Compare the values of the first attribute if (a[comp[0]] === b[comp[0]]) { // if EQ proceed with the next attributes if (comp.length > 1) { return sortComparator(a, b, comp.slice(1)); } else { // if no more attributes then return EQ return 0; } } else { // return less or great return (a[comp[0]] < b[comp[0]] ? -1 : 1) } } // Sort array homes homes.sort(function(a, b) { return sortComparator(a, b, ['state', 'city', 'zip']); }); // display the array homes.forEach(function(home) { console.log(home.h_id, home.city, home.state, home.zip, home.price); });
结果是
$ node sort 4 Bevery Hills CA 90210 319250 5 New York NY 00010 962500 3 Dallas TX 75201 162500
和另一种
homes.sort(function(a, b) { return sortComparator(a, b, ['city', 'zip']); });
结果
$ node sort 4 Bevery Hills CA 90210 319250 3 Dallas TX 75201 162500 5 New York NY 00010 962500
用于sorting多个数组对象字段。 在arrprop
数组中input您的字段名称,如["a","b","c"]
然后传入我们要sorting的第二个参数arrsource
实际源。
function SortArrayobject(arrprop,arrsource){ arrprop.forEach(function(i){ arrsource.sort(function(a,b){ return ((a[i] < b[i]) ? -1 : ((a[i] > b[i]) ? 1 : 0)); }); }); return arrsource; }