按特定顺序对对象数组进行排序

时间:2014-05-11 22:24:55

标签: javascript arrays sorting

我有一个从API调用返回的对象数组,我需要将其排序为特定格式。

我尝试按字母顺序排列<{1}} 除了前三个和最后一个项目。例如,像这样:

  1. &#34;爱尔兰&#34;
  2. &#34;英国&#34;
  3. &#34;美国&#34;
  4. ...其他国家/地区,按字母顺序排列......
  5. &#34;其他地方&#34;
  6. 我考虑过使用destination_country_id,据我所知,我可以轻松地按字母顺序对它们进行排序,但到目前为止,我还没有成功地弄清楚如何实现所需的输出。

    API响应

    array.sort()

5 个答案:

答案 0 :(得分:4)

可能不是最有效的方法,但它是ES3,不需要任何库,并且相当容易理解。另外假设您想在destination_country_name

上按字母顺序排序

的Javascript

// where x is your array of objects
x.sort(function (a, b) {
    // sorts everything alphabetically
    return a.destination_country_name.localeCompare(b.destination_country_name);
}).sort(function (a, b) {
    // moves only this to country to top
    return +(!b.destination_country_name.localeCompare('United States'));
}).sort(function (a, b) {
    // moves only this to country to top
    return +(!b.destination_country_name.localeCompare('United Kingdom'));
}).sort(function (a, b) {
    // moves only this to country to top
    return +(!b.destination_country_name.localeCompare('Ireland'));
}).sort(function (a, b) {
    // moves only this to country to bottom
    return +(!a.destination_country_name.localeCompare('Everywhere Else'));
});

console.log(JSON.stringify(x, ['destination_country_name']));

输出

[{"destination_country_name":"Ireland"},
 {"destination_country_name":"United Kingdom"},
 {"destination_country_name":"United States"},
 {"destination_country_name":"France"},
 {"destination_country_name":"Spain"},
 {"destination_country_name":"Everywhere Else"}]

jsFiddle

我们甚至可以更进一步,使用上面的例子来创建一个可重用的函数,比如。

的Javascript

function sorter(array, funcs, orders) {
    funcs = funcs || {};
    orders = orders || {};
    array.sort(funcs.general);
    if (Array.isArray(orders.top)) {
        orders.top.slice().reverse().forEach(function(value) {
            array.sort(funcs.top.bind(value));
        });
    }

    if (Array.isArray(orders.bottom)) {
        orders.bottom.forEach(function(value) {
            array.sort(funcs.bottom.bind(value));
        });
    }

    return array;
}

sorter(x, {
    general: function (a, b) {
        return a.destination_country_name.localeCompare(b.destination_country_name);
    },
    top: function (a, b) {
        return +(!b.destination_country_name.localeCompare(this));
    },
    bottom: function (a, b) {
        return +(!a.destination_country_name.localeCompare(this));
    }
}, {
    top: ['Ireland', 'United Kingdom', 'United States'],
    bottom: ['Everywhere Else']
});

jsFiddle

现在,您可以通过解析不同的比较函数轻松地对不同的属性进行排序,并定义应该位于顶部或底部的值。

我使用的是ECMA5方法,但您可以轻松地使用ECMA3。

答案 1 :(得分:1)

您可以为每个对象提供排序顺序&#39;属性。指定已知的前3个和最后一个,并为所有其他值指定相同的值,大于前三个,小于最后一个。然后按排序顺序排序数组,然后按字母顺序排序;

  

var arr = [{&#34; destination_country_id&#34;:null,&#34; primary_cost&#34;:&#34; 9.50&#34;,     &#34; region_id&#34;:null,&#34; destination_country_name&#34;:&#34; Everywhere Else&#34;,   },{&#34; destination_country_id&#34;:105,&#34; primary_cost&#34;:&#34; 8.00&#34;,     &#34; region_id&#34;:null,&#34; destination_country_name&#34;:&#34;英国&#34;,   },{&#34; destination_country_id&#34;:209,&#34; primary_cost&#34;:&#34; 9.50&#34;,     &#34; region_id&#34;:null,&#34; destination_country_name&#34;:&#34;美国&#34;,   },{&#34; destination_country_id&#34;:123,&#34; primary_cost&#34;:&#34; 5.00&#34;,     &#34; region_id&#34;:null,&#34; destination_country_name&#34;:&#34; Ireland&#34;,},{     &#34; destination_country_id&#34;:185,&#34; primary_cost&#34;:&#34; 5.00&#34;,     &#34; region_id&#34;:null,&#34; destination_country_name&#34;:&#34; France&#34;,},{     &#34; destination_country_id&#34;:145,&#34; primary_cost&#34;:&#34; 5.00&#34;,     &#34; region_id&#34;:null,&#34; destination_country_name&#34;:&#34; Spain&#34;,}]

var s= "destination_country_name",
order= ["Ireland", "United Kingdom", 
"United States", "Everywhere Else"];

arr.forEach(function(itm){
    var i= order.indexOf(itm[s]);
    if(i!= -1) itm.sort_order= i== 3? 1e50: i;
    else itm.sort_order= 10;
});

arr.sort(function(a, b){
    var d= a.sort_order- b.sort_order;
    if(d===0){
        if(a[s]=== b[s]) return 0;
        return a[s]>b[s]? 1: -1;
    }
    return d;
});
JSON.stringify(arr)
/*  returned value: (String)[{
        "destination_country_id": 123, "primary_cost": "5.00", "region_id": null, 
        "destination_country_name": "Ireland", "sort_order": 0
    },{
        "destination_country_id": 105, "primary_cost": "8.00", "region_id": null, 
        "destination_country_name": "United Kingdom", "sort_order": 1
    },{
        "destination_country_id": 209, "primary_cost": "9.50", "region_id": null, 
        "destination_country_name": "United States", "sort_order": 2
    },{
        "destination_country_id": 185, "primary_cost": "5.00", "region_id": null, 
        "destination_country_name": "France", "sort_order": 10
    },{
        "destination_country_id": 145, "primary_cost": "5.00", "region_id": null, 
        "destination_country_name": "Spain", "sort_order": 10
    },{
        "destination_country_id": null, "primary_cost": "9.50", "region_id": null, 
        "destination_country_name": "Everywhere Else", "sort_order": 1e+50
    }
]
*/

答案 2 :(得分:1)

我认为对数组进行排序的最有效方法是首先找到数组中"Everywhere Else""UK""Ireland""US"的位置,删除它们,然后对数组的其余部分进行排序。这比听起来简单

fiddle

var data = [
    {"destination_country_name": "Everywhere Else"},
    {"destination_country_name": "United Kingdom"},
    {"destination_country_name": "United States"},
    {"destination_country_name": "Ireland"},
    {"destination_country_name": "France"},
    {"destination_country_name": "Spain"}     ];
//removed the other elements just to make the example cleaner
var keep = ["Everywhere Else", "Ireland", "United Kingdom", "United States"];
//keep is the elements you want in the front; order them exactly at you want them ordered
var top = [];
//this is our holder array to hold the objects for the strings in keep

for (var i = 0; i < keep.length; i++) {
    var index = function () {
        for (var j = 0; j < data.length; j++){    //loop through data
            if (data[j].destination_country_name == keep[i])
                return data[j];    //return the object if it's name matches the one in keep
        }
    }
    if (index > -1){        //if the object is in the array (index != -1)
        top.push(data[index]);    //push the object to our holder array
        data.splice(index, 1);    //splice the object out of the original array
    }
}
//after this loop, those other objects will have been removed
//sort the rest of that array of objects
data.sort(function (a, b) {    //use a callback function to specify which parts of
                               //the object need to be sorted
    //basic sorting/compare algorithm (-1, 0, or 1)
    if (a.destination_country_name > b.destination_country_name)
        return 1;        //if greater
    if (a.destination_country_name < b.destination_country_name)
        return -1;        //if lesser
    return 0;    //otherwise
})

var sorted = top.concat(data), //combine data to the holder array and assign to sorted
    extra = sorted.shift();    //grab the first element ("Everywhere Else") and remove it
    sorted.push(extra);        //add that element to the end of the array
console.log(sorted);

或者,如果您知道这四个地方(EE,UK,US和Ireland)将始终是阵列中的前4个元素,您可以执行以下操作:

var data = [
    {"destination_country_name": "Everywhere Else"},
    {"destination_country_name": "United Kingdom"},
    {"destination_country_name": "United States"},
    {"destination_country_name": "Ireland"},
    {"destination_country_name": "France"},
    {"destination_country_name": "Spain"}     ];

var top = data.slice(0,4);
data.sort(function (a, b) {
    if (a.destination_country_name > b.destination_country_name)
        return 1;
    if (a.destination_country_name < b.destination_country_name)
        return -1;
    return 0;
})

var sorted = top.concat(data),
        extra = sorted.shift();
        sorted = sorted.push(extra);    //put "Everywhere Else" at the end of the array

请注意这是如何更有效(并且更简单!),因为您不需要找到这四个元素。

答案 3 :(得分:-1)

如果您提供的数组被称为list,您可以使用以下调用对其进行排序:

list.sort(function (item1, item2) {
    if (item1.destination_country_name < item2.destination_country_name) {
        return -1;
    }
    return 1;
});

答案 4 :(得分:-3)

你可以使用下划线sortBy方法:

a=[{obj:'first3'},{obj:'first2'},{obj:'first1'},{obj:'z'},{obj:'m'},{obj:'c'},{obj:'end3'},{obj:'end2'},{obj:'end1'}]
a=_.sortBy(a,function (t,i){if (i<=2) return String.fromCharCode(0);if(i>=a.length-3) return String.fromCharCode(255);return t.obj })

console.log(JSON.stringify(a))

[{"obj":"first3"},{"obj":"first2"},{"obj":"first1"},{"obj":"c"},{"obj":"m"},{"obj":"z"},{"obj":"end3"},{"obj":"end2"},{"obj":"end1"}]

http://jsfiddle.net/43Q8h/