首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Javascript自然排序数组/对象并维护索引关联

Javascript自然排序数组/对象并维护索引关联
EN

Stack Overflow用户
提问于 2010-09-30 01:47:49
回答 8查看 27.2K关注 0票数 9

我在Javascript中有一组项目,如下所示:

代码语言:javascript
运行
复制
var users = Array();

users[562] = 'testuser3';
users[16] = 'testuser6';
users[834] = 'testuser1';
users[823] = 'testuser4';
users[23] = 'testuser2';
users[917] = 'testuser5';

我需要对该数组进行排序,以获得以下输出:

代码语言:javascript
运行
复制
users[834] = 'testuser1';
users[23] = 'testuser2';
users[562] = 'testuser3';
users[823] = 'testuser4';
users[917] = 'testuser5';
users[16] = 'testuser6';

注意它是如何按照数组的值进行排序的,并且在对数组进行排序后(这一点很关键),值与索引的关联仍然保持不变。我一直在寻找这个问题的解决方案,尝试着去实现它,但却碰壁了。

顺便说一句,我知道这在技术上不是一个数组,因为这意味着索引总是从0到n迭代,其中n+1是进行n的计数。另外,如果有区别的话,我不会使用jquery。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-09-30 03:02:41

使用评论中的想法,我提出了以下解决方案。naturalSort函数是我在谷歌上找到的,我对它进行了修改,以对多维数组进行排序。基本上,我使用户数组成为一个多维数组,第一个索引是用户id,第二个索引是用户名。所以:

代码语言:javascript
运行
复制
users[0][0] = 72;
users[0][1] = 'testuser4';
users[1][0] = 91;
users[1][1] = 'testuser2';
users[2][0] = 12;
users[2][1] = 'testuser8';
users[3][0] = 3;
users[3][1] = 'testuser1';
users[4][0] = 18;
users[4][1] = 'testuser7';
users[5][0] = 47;
users[5][1] = 'testuser3';
users[6][0] = 16;
users[6][1] = 'testuser6';
users[7][0] = 20;
users[7][1] = 'testuser5';

然后,我对数组进行了排序,以获得以下输出:

代码语言:javascript
运行
复制
users_sorted[0][0] = 3;
users_sorted[0][1] = 'testuser1';
users_sorted[1][0] = 91;
users_sorted[1][1] = 'testuser2';
users_sorted[2][0] = 47;
users_sorted[2][1] = 'testuser3';
users_sorted[3][0] = 72;
users_sorted[3][1] = 'testuser4';
users_sorted[4][0] = 20;
users_sorted[4][1] = 'testuser5';
users_sorted[5][0] = 16;
users_sorted[5][1] = 'testuser6';
users_sorted[6][0] = 18;
users_sorted[6][1] = 'testuser7';
users_sorted[7][0] = 12;
users_sorted[7][1] = 'testuser8';

执行此操作的代码如下:

代码语言:javascript
运行
复制
function naturalSort(a, b) // Function to natural-case insensitive sort multidimensional arrays by second index
{

    // setup temp-scope variables for comparison evauluation
    var re = /(-?[0-9\.]+)/g,
        x = a[1].toString().toLowerCase() || '',
        y = b[1].toString().toLowerCase() || '',
        nC = String.fromCharCode(0),
        xN = x.replace( re, nC + '$1' + nC ).split(nC),
        yN = y.replace( re, nC + '$1' + nC ).split(nC),
        xD = (new Date(x)).getTime(),
        yD = xD ? (new Date(y)).getTime() : null;
    // natural sorting of dates
    if ( yD )
        if ( xD < yD ) return -1;
        else if ( xD > yD ) return 1;
    // natural sorting through split numeric strings and default strings
    for( var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++ ) {
        oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc];
        oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc];
        if (oFxNcL < oFyNcL) return -1;
        else if (oFxNcL > oFyNcL) return 1;
    }
    return 0;
}

// Set values for index
    var users = Array();
    var temp = Array();

    users.push(Array('72', 'testuser4'));
    users.push(Array('91', 'testuser2'));
    users.push(Array('12', 'testuser8'));
    users.push(Array('3', 'testuser1'));
    users.push(Array('18', 'testuser7'));
    users.push(Array('47', 'testuser3'));
    users.push(Array('16', 'testuser6'));
    users.push(Array('20', 'testuser5'));

// Sort the array
    var users_sorted = Array();
    users_sorted = users.sort(naturalSort);
票数 2
EN

Stack Overflow用户

发布于 2010-09-30 02:06:07

数组元素的顺序由索引定义。因此,即使您以不同的顺序指定值,这些值也将始终以其索引的顺序存储,并且未定义的索引为undefined

代码语言:javascript
运行
复制
> var arr = [];
> arr[2] = 2;
> arr[0] = 0;
> arr
[0, undefined, 2]

现在,如果您想要存储索引和值对,您将需要一个不同的数据结构,可能是这样的数组数组:

代码语言:javascript
运行
复制
var arr = [
    [562, 'testuser3'],
    [16, 'testuser6'],
    [834, 'testuser1'],
    [823, 'testuser4'],
    [23, 'testuser2'],
    [917, 'testuser5']
];

可以使用此比较函数对其进行排序:

代码语言:javascript
运行
复制
function cmp(a, b) {
    return a[1].localeCompare(b[1]);
}
arr.sort(cmp);

结果是这个数组:

代码语言:javascript
运行
复制
[
    [834, 'testuser1'],
    [23, 'testuser2'],
    [562, 'testuser3'],
    [823, 'testuser4'],
    [917, 'testuser5'],
    [16, 'testuser6']
]
票数 26
EN

Stack Overflow用户

发布于 2010-09-30 03:01:57

如果我没理解错的话,,你使用数组的方式并不是为了使用数组。实际上,初始化样式

代码语言:javascript
运行
复制
// Don't do this!
var array = new Array();
array[0] = 'value';
array[1] = 'value';
array[2] = 'value';

错误地讲授了有关数组的性质和用途的内容。数组是项的有序列表,从零开始索引。创建数组的正确方法是使用数组文字

代码语言:javascript
运行
复制
var array = [
    'value',
    'value',
    'value'
]

索引是基于指定项的顺序隐含的。创建一个数组并设置users[562] = 'testuser3' 意味着列表中至少还有562个其他用户,并且您有理由在此时只知道第563个用户。

在您的示例中,索引是data,而is不表示set中项目的顺序。您要查找的是地图或字典,在JavaScript中由纯对象表示

代码语言:javascript
运行
复制
var users = {
    562: 'testuser3',
    16:  'testuser6',
    834: 'testuser1',
    823: 'testuser4',
    23:  'testuser2',
    917: 'testuser5'
}

现在,您的set 没有订单,但有有意义的键。在这里,您可以按照galambalazs's advice创建对象键的数组:

代码语言:javascript
运行
复制
var userOrder;
if (typeof Object.keys === 'function') {
    userOrder = Object.keys(users);
} else {
    for (var key in users) {
        userOrder.push(key);
    }
}

…然后对其进行排序:

代码语言:javascript
运行
复制
userOrder.sort(function(a, b){
    return users[a].localeCompare(users[b]);
});
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3824392

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档