【问题标题】:Sorting multiple arrays at once一次对多个数组进行排序
【发布时间】:2012-12-07 06:15:43
【问题描述】:

我有 3 个数组:

  • 数组 1 是“姓名”John、Jim、Jack、Jill

  • 数组 2 是“年龄”25、30、31、22

  • 数组 3 是“性别”男、男、男、女

我将这些都列在一个带有可排序标题的表中。现在排序工作正常,例如按“名称”列排序。我怎样才能让它对“年龄”和“性别”数组进行排序以保持正确。我需要同时对所有 3 个进行排序。

_nameArray.sort(function(a, b){
    return ((a < b) ? -1 : ((a > b) ? 1 : 0));
})

希望解释清楚。

不,结构不能改变,事情的方式必须是 3 个数组,而不是一个,只需按数组中的字段排序。

【问题讨论】:

  • 听起来你应该改用对象。
  • 是的,单个对象数组更适合这个。
  • 如果您使用的是外部源,并且无法更改所获得的内容,我会说将它们解析为本地对象并使用它们。
  • 你们有没有一个例子来获取多个数组,将它们转换为对象,对它们进行排序,然后将它们转换回 3 个可用的数组?这对我个人来说是第一次。

标签: javascript jquery


【解决方案1】:

尽管从多个数组构造对象可能是理想的。您也可以使用 indirection 在没有对象创建开销的情况下做到这一点。

/* An array of indexes */
var idx = [];
for (var i = 0; i < Name.length; i++) {
    idx.push(i);
}

/* A shorthand function */
var comparator = function(arr) {
    return function(a, b) {
        return ((arr[a] < arr[b]) ? -1 : ((arr[a] > arr[b]) ? 1 : 0));
    };
};

/* Sort by Age */
idx = idx.sort(comparator(Age));

/* Get the sorted order */
for (var i = 0; i < Name.length; i++) {
    console.log(Name[idx[i]], Age[idx[i]], Gender[idx[i]]);
}​

idx 数组包含指向其他数组元素的索引,idx[i]。通过使用间接,您可以访问NameAgeGender 中的元素;即Name[idx[i]]

如果性能是一个问题,那么使用就地排序构建对象可能会更快,如果你只做一次。否则,我会使用间接而不接触真正的数组。

There you go.

注意comparator 函数只是一个示例,您需要根据自己的标准实际创建自己的比较器函数。

【讨论】:

  • 很好,比我写的答案更通用。
  • @Alexander:太棒了!非常令人印象深刻。
【解决方案2】:

已经尝试过制作对象(如某些 cmets 中所建议的那样),我不确定增加的复杂性是否值得,但无论如何都会在此处发布以防万一。在这种特殊情况下,Person 对象几乎没有什么用途,可能更有用的是一个聚合对象 (PersonSet),它将存储联合数据、对其进行排序并处理每种类型特征的列表作为输入和输出。 (jsfiddle)

var names = ['John', 'Jim', 'Jack', 'Jill'],
    ages = [25, 30, 31, 22],
    genders = ['male', 'male', 'male', 'female'];
function Person(name, age, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}
function PersonSet(names, ages, genders) {
    this.content = [];
    for (var i = 0; i < names.length; i++) {
        this.content.push(new Person(names[i], ages[i], genders[i]));
        // (alternatively...)
        // this.content.push({name: names[i], age: ages[i], gender: 
        //     genders[i]});
    }
    this.sort = function(aspect) {
        this.content.sort(function(a, b) {
            return ((a[aspect] < b[aspect]) ? -1 : 
                ((a[aspect] > b[aspect]) ? 1 : 0));
        });
    };                    
    this.get = function(aspect) {
        var r = [];
        for (var i = 0; i < this.content.length; i++) {
            r.push(this.content[i][aspect]);
        }
        return r;
    }
}
var personSet = new PersonSet(names, ages, genders);
personSet.sort('age');
console.log(personSet.get('name'), personSet.get('age'), 
            personSet.get('gender'));​​​​​​​​​​

【讨论】:

  • 嘿,从 8 年多以后。 :) 好吧,有趣的是,将您的方法视为类类结构,但没有实际定义类。那是某种众所周知的“伪”结构吗?与传统的真实类方法相比,它有什么优点或缺点吗?最美好的祝愿
  • @ViktorBorítás class 在我写完这个答案后,于 2015 年被引入了 javascript!在那之前,这个答案中显示的函数原型模式是the javascript traditionclass is sometimes (inaccurately?) called syntactic sugar 坐在旧的原型模式之上。
  • 感谢您用历史上的这一有趣事实启发了我。 :) 保重!
【解决方案3】:

如果您想对表格中的数据进行排序,您应该查看Tablesorter

【讨论】:

  • 我已经有一个表格分类器,但是谢谢。问题是它们不携带样式、onclick 等。他们倾向于将其写入并附加到新表中,只保留 td 的 html 自身。
【解决方案4】:

鉴于您的限制,为什么不编写自己的排序函数。在排序函数内部维护所有数组,如:

  1. 找到最低的项目。假设它位于索引 5。现在在所有 3 个数组中将 item@index5 与 item@index0 交换。
  2. 从索引1开始重复上述逻辑...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多