Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/376.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

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_Overriding_Overloading - Fatal编程技术网

如何重写JavaScript数组排序方法?

如何重写JavaScript数组排序方法?,javascript,sorting,overriding,overloading,Javascript,Sorting,Overriding,Overloading,截至10月31日星期一,这个问题仍然没有得到纠正和回答。人们错误地回答了这个问题,好像我要求修改array.sort,但我不是这样要求的 如何使用基数msd algorthim覆盖单个数组而不是array.sort的内置JavaScript排序方法 我有基数msd排序的算法,它是 // radix most-significant-bit sort for integers //arr: array to be sorted //begin: 0 //end: length of array /

截至10月31日星期一,这个问题仍然没有得到纠正和回答。人们错误地回答了这个问题,好像我要求修改array.sort,但我不是这样要求的

如何使用基数msd algorthim覆盖单个数组而不是array.sort的内置JavaScript排序方法

我有基数msd排序的算法,它是

// radix most-significant-bit sort for integers
//arr: array to be sorted
//begin: 0
//end: length of array
//bit: maximum number of bits required to represent numbers in arr
function radixsort (arr, begin, end, bit) {
    var i, j, mask;
    i = begin;
    j = end;
    mask = 1 << bit;
    while(i < j) {
        while(i < j && !(arr[i] & mask)) {
            ++i;
        }
        while(i < j && (arr[j - 1] & mask)) {
            --j;
        }
        if(i < j) {
            j--;
            var tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
            i++;
        }
    }
    if(bit && i > begin) {
        radixsort(arr, begin, i, bit - 1);   //    <=== RECURSIVE FUNCTION
    }
    if(bit && i < end) {
        radixsort(arr, i, end, bit - 1);     //    <=== RECURSIVE FUNCTION
    }
}

因此,当我调用homes.sort时,我希望它使用上面的基数排序数组,根据价格对整个homes[x]数组进行排序。我该怎么做?

你的问题是问两件事:

如何对数组调用sort,但调用array.sort以外的函数? 如何使排序算法在不硬编码的情况下使用特定字段? 第一个问题的答案是在homes对象本身上附加一个排序方法:

homes.sort = function () {radixSort(homes, 0, homes.length, bit);}
正如一位评论者和其他回答者所指出的那样,这样做会让人非常困惑。首先,Arrays.sort接受第二个参数,即比较函数。基数排序是基于分布的排序,而不是基于比较的排序,因此以这种方式重写排序没有多大意义。如果有人传入比较函数,您将忽略它

但还有一个问题。您编写的radixSort不起作用,因为它不比较价格。其中一个答案对价格进行了硬编码,但你说你不喜欢这种情况。可以按如下方式解决此问题:添加第五个参数,即字段名。如果未定义,请使用数组元素本身,否则请选择字段。像这样的东西没有经过测试:

function radixsort (arr, begin, end, bit, field) {
    var i = begin, j = end , mask = 1 << bit;
    // Use the value of the field at i if present, otherwise the whole element
    var at = function (i) {return field in arr ? arr[i][field] : arr[i]};
    while (i < j) {
        while (i < j && !(arr.at(i) & mask)) {
            ++i;
        }
        while (i < j && (arr.at(j-1) & mask)) {
            --j;
        }
        if (i < j) {
            j--;
            var tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
            i++;
        }
    }
    if (bit && i > begin) {
        radixsort(arr, begin, i, bit - 1);
    }
    if (bit && i < end) {
        radixsort(arr, i, end, bit - 1);
    }
}
但是,请记住以下注意事项:


警告:如果price是浮点值,则基数排序可能不起作用。您最好只使用Array.prototype.sort并传入一个比较器,在不同的字段上进行排序。

您的问题有两个:

如何对数组调用sort,但调用array.sort以外的函数? 如何使排序算法在不硬编码的情况下使用特定字段? 第一个问题的答案是在homes对象本身上附加一个排序方法:

homes.sort = function () {radixSort(homes, 0, homes.length, bit);}
正如一位评论者和其他回答者所指出的那样,这样做会让人非常困惑。首先,Arrays.sort接受第二个参数,即比较函数。基数排序是基于分布的排序,而不是基于比较的排序,因此以这种方式重写排序没有多大意义。如果有人传入比较函数,您将忽略它

但还有一个问题。您编写的radixSort不起作用,因为它不比较价格。其中一个答案对价格进行了硬编码,但你说你不喜欢这种情况。可以按如下方式解决此问题:添加第五个参数,即字段名。如果未定义,请使用数组元素本身,否则请选择字段。像这样的东西没有经过测试:

function radixsort (arr, begin, end, bit, field) {
    var i = begin, j = end , mask = 1 << bit;
    // Use the value of the field at i if present, otherwise the whole element
    var at = function (i) {return field in arr ? arr[i][field] : arr[i]};
    while (i < j) {
        while (i < j && !(arr.at(i) & mask)) {
            ++i;
        }
        while (i < j && (arr.at(j-1) & mask)) {
            --j;
        }
        if (i < j) {
            j--;
            var tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
            i++;
        }
    }
    if (bit && i > begin) {
        radixsort(arr, begin, i, bit - 1);
    }
    if (bit && i < end) {
        radixsort(arr, i, end, bit - 1);
    }
}
但是,请记住以下注意事项:


警告:如果price是浮点值,则基数排序可能不起作用。最好只使用Array.prototype.sort并传入一个比较器来对不同字段进行排序。

您不需要重写,只需将比较器函数作为参数传递给sort方法即可

参数的函数签名是函数a,b,其中a是与b比较的项

如果需要不同的sort实现,请将其设置为不同的函数,而不是覆盖默认行为。可以使用以下方法对所有阵列执行此操作:

Array.prototype.radixsort = function ( ...params... )
这样你就可以打电话了

[1,2,3].radixsort(...params...);
或者,您可以将实用程序函数添加到阵列:

其名称为:

Array.radixsort([1,2,3], ...params...);

不需要重写,只需将比较器函数作为参数传递给sort方法

参数的函数签名是函数a,b,其中a是与b比较的项

如果需要不同的sort实现,请将其设置为不同的函数,而不是覆盖默认行为。可以使用以下方法对所有阵列执行此操作:

Array.prototype.radixsort = function ( ...params... )
这样你就可以打电话了

[1,2,3].radixsort(...params...);
或者,您可以将实用程序函数添加到阵列:

其名称为:

Array.radixsort([1,2,3], ...params...);
我认为修改Array.prototype.sort是非常危险的,因为所有其他可能使用sort的代码都会受到影响。下面是代码:

//Just use this function like radixsort(homes,0,homes.length,32)
function radixsort (arr, begin, end, bit) {
    var i, j, mask;
    i = begin;
    j = end;
    mask = 1 << bit;
    while(i < j) {
        while(i < j && !(arr[i].price & mask)) {
            ++i;
        }
        while(i < j && (arr[j - 1].price & mask)) {
            --j;
        }
        if(i < j) {
            j--;
            var tmp = arr[i].price;
            arr[i].price = arr[j].price;
            arr[j].price = tmp;
            i++;
        }
    }
    if(bit && i > begin) {
        radixsort(arr, begin, i, bit - 1);
    }
    if(bit && i < end) {
        radixsort(arr, i, end, bit - 1);
    }
}
//If you really want to modify default sort function:
Array.prototype.sort = function(){
    radixsort(this,0,this.length,32); //Use 'this' to access (get reference) to the array.
}
我认为修改Array.prototype.sort是非常危险的,因为所有其他可能使用sort的代码都会受到影响。下面是代码:

//Just use this function like radixsort(homes,0,homes.length,32)
function radixsort (arr, begin, end, bit) {
    var i, j, mask;
    i = begin;
    j = end;
    mask = 1 << bit;
    while(i < j) {
        while(i < j && !(arr[i].price & mask)) {
            ++i;
        }
        while(i < j && (arr[j - 1].price & mask)) {
            --j;
        }
        if(i < j) {
            j--;
            var tmp = arr[i].price;
            arr[i].price = arr[j].price;
            arr[j].price = tmp;
            i++;
        }
    }
    if(bit && i > begin) {
        radixsort(arr, begin, i, bit - 1);
    }
    if(bit && i < end) {
        radixsort(arr, i, end, bit - 1);
    }
}
//If you really want to modify default sort function:
Array.prototype.sort = function(){
    radixsort(this,0,this.length,32); //Use 'this' to access (get reference) to the array.
}

继续Ray Toal和ZZBOV的讨论:

  function defaultCompare(a, b) {
      var a_str = str(a);
      var b_str = str(b);
      if (a_str < b_str) {
          return -1;
      } else if (a_str > b_str) {
          return 1;
      } else {
          return 0;
      }
   }

   homes.sort = function (compare_func) {
       compare_func = compare_func || defaultCompare;
       RadixSort(this, 0, this.length, 64);
   }

上述内容可能存在拼写错误,但这应该是迈向更完整实施的一步。

继续Ray Toal和Zzbov的讨论:

  function defaultCompare(a, b) {
      var a_str = str(a);
      var b_str = str(b);
      if (a_str < b_str) {
          return -1;
      } else if (a_str > b_str) {
          return 1;
      } else {
          return 0;
      }
   }

   homes.sort = function (compare_func) {
       compare_func = compare_func || defaultCompare;
       RadixSort(this, 0, this.length, 64);
   }

上面可能有输入错误,但这应该是迈向更完整实现的一步。

但是如果我做了上面的示例,radixsort如何知道根据数组的Price属性进行排序?我看到你让函数假设了价格属性
ute存在于数组中,但我想将radixsort函数推广为不采用Price属性。实际上OP从未声称要覆盖array.prototype.sort,这显然是危险和愚蠢的,正如你所说的那样他们只是想使用homes.sort语法。通过使用“覆盖”一词,我认为OP清楚地表明了只对homes数组使用排序方法,而不改变所有数组的行为的愿望。@JiminP或任何人,如果你能帮助我概括这一点,这样我就不必将Price硬编码到基数排序函数中,我会让这个答案正确/被接受。请看我上面的评论。但是如果我做了上面的示例,radixsort如何知道根据数组的Price属性进行排序?我看到你让函数假定数组中存在Price属性,但我想将radixsort函数推广为不假定Price属性。实际上OP从未声称要覆盖array.prototype.sort,这显然是危险和愚蠢的,就像你说的那样他们只是想使用homes.sort语法。通过使用“覆盖”一词,我认为OP清楚地表明了只对homes数组使用排序方法,而不改变所有数组的行为的愿望。@JiminP或任何人,如果你能帮助我概括这一点,这样我就不必将Price硬编码到基数排序函数中,我会让这个答案正确/被接受。请参阅我上面的评论。不要用新的行为覆盖默认函数,这将为将来的调试带来巨大的麻烦。@zzzzBov我倾向于同意你的排序,但我不会把这当作一般性的建议,因为默认函数toString是荒谬的,应该被覆盖我知道你的意思。尽管如此,从技术角度来看,这个问题还是有价值的,因此我编辑了答案以解决您的问题。toString和valueOf是作为所有对象的公共接口使用的特殊情况,预期会覆盖这些值。您必须维护通用接口,以使它们正常工作。您不会从toString返回对象或数字,因此如果要覆盖sort,则必须使其与现有接口一起工作,其中第一个参数是比较器函数。哈!这就是为什么在这种情况下即使不是不可能也很难。基数排序是一种分布排序,而不是比较排序,因此非常正确,将排序视为一种通用方法la-toString和toValue没有任何意义,因为基数排序根本不使用比较器。尽管如此,这个问题本身还是很有趣的,因为OP试图创建一个特定于对象的方法,但是,是的,在这个特定的情况下,这样做根本不是正确的。不要用新的行为覆盖默认函数,这将给未来的调试带来巨大的麻烦。@zzzzBov我倾向于同意你的排序,但我不认为这是一般性的建议,因为默认函数toString是荒谬的,应该被重写我知道你的意思。尽管如此,从技术角度来看,这个问题还是有价值的,因此我编辑了答案以解决您的问题。toString和valueOf是作为所有对象的公共接口使用的特殊情况,预期会覆盖这些值。您必须维护通用接口,以使它们正常工作。您不会从toString返回对象或数字,因此如果要覆盖sort,则必须使其与现有接口一起工作,其中第一个参数是比较器函数。哈!这就是为什么在这种情况下即使不是不可能也很难。基数排序是一种分布排序,而不是比较排序,因此非常正确,将排序视为一种通用方法la-toString和toValue没有任何意义,因为基数排序根本不使用比较器。尽管如此,这个问题本身还是很有趣的,因为OP试图创建一个特定于对象的方法,但是是的,在这个特定的案例中,这根本不是正确的做法。我不想重载/重写Array.sort,只想重载Homes.sortN/A-这个答案不适用,因为我不想重写Array.sort。只有homes.sort,除非另有建议。我不想重载/重写Array.sort,只想重载homes.sortN/A-这个答案不适用,因为我不想重写Array.sort。除非有其他明智的建议,否则只能进行排序。