通过根据属性进行分组来订购javascript数组

时间:2011-12-27 16:02:20

标签: javascript arrays grouping

我正在从搜索网络服务中使用一组json对象来提供jQuery.ui自动完成,我使用category system根据他们的“家庭”对我的对象进行分组

该算法使用一个列表,其中组已经很好地排序,这是我目前无法做到的,所以我想在客户端组织数据。例如,如果我有以下数组:

var resultsArray = [
{"cat": "Category #1", "Id": "10"},
{"cat": "Category #2", "Id": "28"},
{"cat": "Category #1", "Id": "11"},
{"cat": "Category #2", "Id": "21"},
{"cat": "Category #1", "Id": "13"}
];

我想在resultsArray上调用一个方法,所以我回来了

resultsArray = [
{"cat": "Category #1", "Id": "10"},
{"cat": "Category #1", "Id": "11"},
{"cat": "Category #1", "Id": "13"},
{"cat": "Category #2", "Id": "28"},
{"cat": "Category #2", "Id": "21"}
];

按照cat属性进行分组,同时保留现有订单。

首先,我尝试在数组上使用sort方法,通过返回数组中我想要分组的值的位置(假设acs.groupBy包含分组属性的名称:< / p>

items.sort(function(a, b) {
    var aValue = a[acs.groupBy],
    bValue = b[acs.groupBy];
    var indexOfAValue = 0; // should be sthing like items.indexWhere(item[acs.groupBy] === aValue)
    var indexOfBValue = 0; // same thing
    return indexOfAValue - indexOfBValue;
});
带有indexOfAValue的

将是数组中找到A的分组属性的第一个位置,但我找不到一个方法来获取和缓存此值(array的indexOf匹配整个对象)。有没有想过这个?


修改

看起来我给出了错误的例子:) 我不想对类别进行排序。如果类别#2发生在类别#1之前,我想保留此信息

var resultsArray = [
    {"cat": "Category #3", "Id": "39"},
    {"cat": "Category #2", "Id": "28"},
    {"cat": "Category #1", "Id": "11"},
    {"cat": "Category #2", "Id": "21"},
    {"cat": "Category #1", "Id": "18"}
]

将成为(请注意,即使我根据类别对项目进行分组,我也没有更改类别发生的顺序,并且我没有根据他们的ID更改组内的项目顺序)

var resultsArray = [
    {"cat": "Category #3", "Id": "39"},
    {"cat": "Category #2", "Id": "28"},
    {"cat": "Category #2", "Id": "21"},
    {"cat": "Category #1", "Id": "11"},
    {"cat": "Category #1", "Id": "18"}
]

这就是为什么我在上面的示例中尝试通过indexOf(类别)进行排序

2 个答案:

答案 0 :(得分:2)

看起来你只是在寻找一个正常稳定的排序?本机JS排序在大多数浏览器中都是稳定的(过去2年左右的每个现代浏览器都是如此),所以简单地说:

items.sort( function( a, b ){
    return a.Id - b.Id;
} );

通常会有效,但在所有浏览器中都不稳定,所以要做到这一点,请执行以下操作:

for( var i=0... ){
   items[i].index = i;
}
items.sort( function( a, b ){
    return ( a.Id != b.Id ) ? ( a.Id - b.Id ) : ( a.index - b.index );
}

按Id排序,然后按原始顺序排序。

答案 1 :(得分:1)

您走在正确的轨道上,您的sort功能无需复杂:

function group(array) {
    var i, categories = {};
    /* Build a map of categories and minimum indices: */
    for (i = 0; i < resultsArray.length; i++) {
        if (!categories[resultsArray[i].cat]) {
            categories[resultsArray[i].cat] = i;
        }
    }

    /* Sort the array using the minimum index: */
    return resultsArray.sort(function(one, other) {
        return categories[one.cat] - categories[other.cat];
    });
}

示例: http://jsfiddle.net/dn2U5/

这应该让你开始。不幸的是,函数循环遍历数组两次(显然不是最优的)。