Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于javascript的排序函数_Javascript_Sorting - Fatal编程技术网

关于javascript的排序函数

关于javascript的排序函数,javascript,sorting,Javascript,Sorting,背景: 根据某些任务的需要,我需要一个简单的排序函数。为了简单起见,我编写了另一个函数,将内置排序函数包装为: function sortBy(obj, extra, func){ if(typeof func == 'function'){ f = func; } else if(typeof extra != 'function'){ eval('function f(a, b, ai, bi, e){return ' + func + '}'

背景:

根据某些任务的需要,我需要一个简单的排序函数。为了简单起见,我编写了另一个函数,将内置排序函数包装为:

function sortBy(obj, extra, func){
    if(typeof func == 'function'){
        f = func;
    } else if(typeof extra != 'function'){
        eval('function f(a, b, ai, bi, e){return ' + func + '}');
    } else {
        var f = extra;
        extra = null;
    }

    var res = [];
    for(var i in obj){
        if(obj.hasOwnProperty(i)){
            obj[i]._k_ = i;
            res.push(obj[i]);
        }
    }

    res.sort(function(a, b){
        if(f(a, b, a._k_, b._k_, extra)){
            return 1;
        } else {
            return -1;
        }
    })

    return res;
}
我的尝试是:

  • 使直接对对象进行排序成为可能
  • 将原始对象保留为哈希表
  • 允许使用一些简单的语法
  • 比如说,

    var data ={
        12: {age:27, name:'pop', role: 'Programmer'},
        32: {age:25, name:'james', role: 'Accontant'},
        123:{age:19, name:'jerry', role:'Sales Representative'},
        15:{age:22, name:'jerry', role:'Coder'},
        17:{age:19, name:'jerry', role:'Tester'},
        43:{age:14, name:'anna', role: 'Manager'},
        55: {age:31, name:'luke', role:'Analyst'}
    };
    
    有几种用法:

    var b = sortBy(data, '', 'a.age < b.age'); // a simple sort, order by age
    var b = sortBy(data, 19, 'b.age == e');    // pick up all records of age 19, and put them in the beginning
    var b = sortBy(data, function(a, b){return a.name > b.name});  // anonymous sort function is also allowed
    
    var b=sortBy(数据,,'a.ageb.name});//还允许使用匿名排序函数
    
    问题

    虽然它在我们的代码中工作正常,但我想提出一些问题:

  • 使用eval从字符串创建排序函数是否存在潜在问题
  • 有没有关于排序函数返回-1(nagative)、0和1(positive)的故事? 我们可以将代码改为“returnif(f(a,b,a.k,b.k,extra)”,而不是返回1或-1吗?我们发现它在firefox和chrome中都可以工作,但不确定这样做是否安全

  • 我认为传递一个进行比较的函数是合适的

    sort(somedata, function(a, b) {
        return a < b;
    });
    
    排序(一些数据、函数(a、b){
    返回a
    尝试这样做,以便只对一小部分进行评估:

    (小提琴:)

    函数排序(obj、extra、func){
    var f=null;
    if(typeof func=='function'){
    f=func;
    }else if(额外类型!=“函数”){
    f=函数(a、b、ai、bi、e){
    返回值(func);//
    1.使用eval从字符串创建排序函数是否存在潜在问题

    不是本身,但它确实有与调用其他具有字符串的EVE风格函数的相同缺陷,例如“代码> SET TIMEOUT())/>代码>或<代码>函数()/代码>构造函数。只要您相信字符串的源,就没有真正的问题。但是,我将考虑使用<代码>函数< /COD>构造函数代替:

    f = new Function(a, b, ai, bi, e, 'return ' + func);
    
    它比评估函数声明更易于管理,而且肯定更合适

    2.有没有关于排序函数返回-1(否定)、0和1(肯定)的故事

    不太理解问题的这一部分,但如果比较中的两项相同,则函数似乎无法解决该怎么办。根据结果,返回的值应小于0、0或大于0。最好的方法是使用
    String.prototype.localeCompare()

  • 多亏了安迪,我们把代码改为

    var f=新函数('a,b,ai,bi,e','return'+func)

  • 请注意,参数应作为字符串传入,请检查:

  • 关于第二个问题,我认为这是因为我们试图使排序函数更明确。 比如说,

    排序([1,2,3,5,1],“'a[1,1,2,3,5]

  • 对我们来说,‘a 另一个例子,“a.age 这就是我要问的原因,我们能用真或假来代替-1,0,1吗

    我们继续做一些小测试,找出一些东西,希望与大家分享

    例如:

    var b = [
        {age:27, name:'pop 2', role: 'Programmer'},
        {age:19, name:'james', role: 'Accontant'},
        {age:19, name:'jerry', role:'Sales Representative'},
        {age:22, name:'jerry', role:'Coder'},
        {age:19, name:'jerry', role:'Tester'},
        {age:14, name:'anna', role: 'Manager'},
        {age:19, name:'luke', role:'Analyst'},
        {age:27, name:'pop', role: 'Programmer'},
        {age:14, name:'anna 2', role: 'Manager'}
    ];
    
    b.sort(function(a, b) {return a.age - b.age > 0? 1: -1}); // #1
    b.sort(function(a, b) {return a.age > b.age});  // #2
    b.sort(function(a, b) {return a.age - b.age});  // #3
    
    尽管上述排序返回相同的结果,但请尝试以下方法:

    b.sort(function(a, b) {return a.age - b.age < 0? -1: 1});  // #4
    
    b.sort(函数(a,b){返回a.age-b.age<0?-1:1});//4
    
    在此语句中,记录仍按年龄排序,但在同一年龄组中顺序相反

    #1和#2碰巧与#3相同。如果浏览器使用不同的算法来实现排序功能, 有可能#1和#2的行为类似于#4。如果严格要求结果的顺序,则需要 当“a”等于项“b”时,显式返回0

    此外,正如Andy指出的,在某些情况下(例如#4),如果不显式返回0,可能会进行不必要的交换,这可能会影响性能

    我们之前没有注意到这一点的原因是,我们不关心提供记录的团队中的订单
    是按特定属性排序的。

    为什么不使用已经存在的排序函数?@dave he是:“我编写了另一个函数,将内置排序函数包装为…”如果我不记得错误的排序函数仅适用于数组对象,对吗?从技术上讲,这比较慢。在原始版本中,
    eval
    在排序之前只运行一次。在您的版本中,每次调用排序函数时,您都会调用编译器。
    f=new function(…)
    在这两种情况下都更合适。谢谢你的第一个答案。这是一个很好的建议我应该在我的答案中指出的一点是性能。如果一个项目不需要移动,应该返回
    0
    ,因为这样做的事情更少。例如,一个已经半排序的数组
    [1,1,1,5,3,4]
    。尽管前三项已经就位,但您仍在告诉排序实现移动它们,因此需要做更多的工作。我认为这取决于浏览器如何实现排序功能。例如,在语句#1和#2中,我认为性能与#3(标准的)没有区别,因为已排序的项目保持其原始顺序,是吗?当然在#4中,这需要额外的操作。
    var b = [
        {age:27, name:'pop 2', role: 'Programmer'},
        {age:19, name:'james', role: 'Accontant'},
        {age:19, name:'jerry', role:'Sales Representative'},
        {age:22, name:'jerry', role:'Coder'},
        {age:19, name:'jerry', role:'Tester'},
        {age:14, name:'anna', role: 'Manager'},
        {age:19, name:'luke', role:'Analyst'},
        {age:27, name:'pop', role: 'Programmer'},
        {age:14, name:'anna 2', role: 'Manager'}
    ];
    
    b.sort(function(a, b) {return a.age - b.age > 0? 1: -1}); // #1
    b.sort(function(a, b) {return a.age > b.age});  // #2
    b.sort(function(a, b) {return a.age - b.age});  // #3
    
    b.sort(function(a, b) {return a.age - b.age < 0? -1: 1});  // #4