此问题仍未在10月31日星期一之前得到纠正 (人们错误地回答它,好像我要求修改array.sort但我不是问那个)
如何使用radix-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
}
}
我的JavaScript对象数组是:
homes[0].price;
homes[0].address;
homes[0].city;
homes[0].state;
homes[0].zip;
因此,当我调用“homes.sort()
”时 - 我希望它使用上面的homes[x]
数组基于price
对整个radix sort
数组进行排序。 我该怎么做?
答案 0 :(得分:5)
您无需覆盖sort
function,只需将比较器函数作为参数传递给sort
方法。
参数的函数签名为function (a, b)
,其中a
是与b
进行比较的项目。
如果需要不同的sort实现,请将其设置为不同的函数,而不是覆盖默认行为。您可以使用以下命令对所有阵列执行此操作:
Array.prototype.radixsort = function ( ...params... )
这将允许您致电
[1,2,3].radixsort(...params...);
或者,您可以向Array
添加实用程序功能:
Array.radixsort = function ( ...params... )
将被称为:
Array.radixsort([1,2,3], ...params...);
答案 1 :(得分:1)
我认为修改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.
}
答案 2 :(得分:0)
扩展Ray Toal和zzzzBov的讨论:
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);
}
上面可能存在拼写错误,但这应该是迈向更完整实施的一步。
答案 3 :(得分:-2)
你的问题是要问两件事:
sort
但是调用Array.sort
以外的函数?第一个问题的答案是在sort
对象本身附加homes
方法:
homes.sort = function () {radixSort(homes, 0, homes.length, bit);}
作为其中一位评论者和其他回答者指出,这样做可能会非常混乱。首先,Arrays.sort
采用第二个参数,它是一个比较函数。基数排序是基于分布的排序,而不是基于比较的排序,因此以这种方式“覆盖”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);
}
}
现在你可以说:
homes.sort = function () {radixSort(homes, 0, homes.length, 64, 'price');}
但是,请记住以下警告:
CAVEAT :如果price
是浮点值,则基数排序可能不起作用。最好的办法是只使用Array.prototype.sort
并传入比较器对不同的字段进行排序。