按属性值对对象数组进行排序

1693

我使用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"
    }
];

如何使用JavaScript创建一个按照对象的price属性以升序降序排序的函数?


最快的方法是使用isomorphic sort-array模块,它在浏览器和Node中都可以本地运行,支持任何类型的输入、计算字段和自定义排序顺序。 - Lloyd
相关:按对象属性值对数组进行数字排序 - Sebastian Simon
35个回答

5

我还使用了某种评分和多字段排序:

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}
]

4

对于普通元素值的数组:

function sortArrayOfElements(arrayToSort) {
    function compareElements(a, b) {
        if (a < b)
            return -1;
        if (a > b)
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareElements);
}

e.g. 1:
var array1 = [1,2,545,676,64,2,24]
output : [1, 2, 2, 24, 64, 545, 676]

var array2 = ["v","a",545,676,64,2,"24"]
output: ["a", "v", 2, "24", 64, 545, 676]

对于一个对象数组:

function sortArrayOfObjects(arrayToSort, key) {
    function compareObjects(a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareObjects);
}

e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]

output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]

3

如果您使用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);}); 

3

以下是从书籍《JavaScript: The Good Parts》中精选出来的一份优雅实现的略微修改版。

注意:这个版本的by稳定的。它在执行下一个链接排序时保留了第一个排序的顺序。

我添加了isAscending参数,并将其转换为ES6标准和作者推荐的“较新”好方法。

您可以按升序或降序排序,并通过多个属性链接排序。

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"}
// ]


我们能否按照id对{"first":"Curly","last":"Howard", "property" : {"id" : "1"}}类型的数组进行排序? - Vishal Kumar Sahu
是的,这个函数必须稍微修改一下,以接受一个新参数,比如说nestedName。然后你可以使用name="property",nestedName="id"来调用它。 - mythicalcoder

3
创建一个函数,并使用以下代码基于输入进行排序。
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"

 }];

 function sortList(list,order){
     if(order=="ASC"){
        return list.sort((a,b)=>{
            return parseFloat(a.price) - parseFloat(b.price);
        })
     }
     else{
        return list.sort((a,b)=>{
            return parseFloat(b.price) - parseFloat(a.price);
        });
     }
 }

 sortList(homes,'DESC');
 console.log(homes);

2
你需要两个函数。
function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

然后,您可以将此应用于任何对象属性:
 data.sort((a, b) => desc(parseFloat(a.price), parseFloat(b.price)));

let data = [
    {label: "one", value:10},
    {label: "two", value:5},
    {label: "three", value:1},
];

// sort functions
function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

// DESC
data.sort((a, b) => desc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>DESCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);

// ASC
data.sort((a, b) => asc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>ASCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);


2

多个数组对象字段排序。 将您的字段名称输入到arrprop数组中,如["a","b","c"], 然后在第二个参数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;
}

1
Array.prototype.sortBy = function(callback) {
  return this.sort((a, b) => callback(a) - callback(b))
}

[1,2,3,2].sortBy(i => i) // [1, 2, 2, 3]
[1,2,3,2].sortBy(i => i == 2) // [1, 3, 2, 2]

0
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)
})

0

嗨,在阅读了这篇文章之后,我为自己的需求编写了一个sortComparator,并具有比较多个JSON属性的功能,我想与您分享。

此解决方案仅按升序比较字符串,但可以轻松扩展每个属性以支持:反向排序、其他数据类型、使用区域设置、转换等

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接