[英]Array.sort get different result in IOS
it's a simple code, but returns different results in Andriod and Iphone. 这是一个简单的代码,但在Andriod和Iphone中返回不同的结果。
var str = [1,2,3,4,5].sort(function () {
return -1;
})
document.write(str);
In MDN( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort ) it says 在MDN( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort )中,它说
So the result should be 1,2,3,4,5. 所以结果应该是1,2,3,4,5。 But is Iphone it shows 5,4,3,2,1
但它是Iphone它显示5,4,3,2,1
Here is a link for you to try this code. 这是您尝试此代码的链接。 http://www.madcoder.cn/demos/ios-test.html
http://www.madcoder.cn/demos/ios-test.html
And after I did more and more test. 在我做了越来越多的测试之后。 I found Iphone is doing a different sorting.
我发现Iphone正在进行不同的排序。 Here is a link shows how sort works: http://www.madcoder.cn/demos/ios-test2.html
这是一个显示排序如何工作的链接: http : //www.madcoder.cn/demos/ios-test2.html
The javascript engines use different algorithms for their sort function. javascript引擎使用不同的算法进行排序功能。 Since the compare function doesn't compare values, you get the result of the inner workings of the different algorithms instead of having a sorted result.
由于compare函数不比较值,因此您可以获得不同算法的内部工作结果,而不是具有排序结果。
Looking at the source code of V8 engine (Chrome) and JavaScriptCore (which seems to be used by Safari, or at least the sort function gives the same result, so I guess it uses the same kind of algorithm), you can view the functions that are being used. 查看V8引擎(Chrome)和JavaScriptCore的源代码(似乎是Safari使用的,或者至少sort函数给出相同的结果,所以我猜它使用相同类型的算法),你可以查看函数正在使用。
Not that it might not be exactly the functions used, what's important is that the algorithms are different. 并不是说它可能不是所使用的功能,重要的是算法是不同的。 They give the same result if you actually compare values, but if not, the result is dependent on the way they operate, not on the function itself.
如果您实际比较值,它们会给出相同的结果,但如果不是,则结果取决于它们的运行方式,而不是函数本身。 At least not completely.
至少不完全。
Here's V8 engine sorting function. 这是V8发动机分拣功能。 You'll see that for arrays bigger than 10 elements, the algorithm isn't the same, so the result for arrays smaller than 10 elements is different than for those bigger than 10 elements.
您会看到,对于大于10个元素的数组,算法不一样,因此小于10个元素的数组的结果与大于10个元素的数组的结果不同。
You can find following algorithms here: https://code.google.com/p/chromium/codesearch#chromium/src/v8/src/js/array.js&q=array&sq=package:chromium&dr=C 您可以在此处找到以下算法: https : //code.google.com/p/chromium/codesearch#chromium/src/v8/src/js/array.js&q=array&sq=package : chromium&dr=C
comparefn = function(a, b) { return -1 } var InsertionSort = function InsertionSort(a, from, to) { for (var i = from + 1; i < to; i++) { var element = a[i]; for (var j = i - 1; j >= from; j--) { var tmp = a[j]; var order = comparefn(tmp, element); if (order > 0) { a[j + 1] = tmp; } else { break; } } a[j + 1] = element; } console.log(a); } var GetThirdIndex = function(a, from, to) { var t_array = new InternalArray(); // Use both 'from' and 'to' to determine the pivot candidates. var increment = 200 + ((to - from) & 15); var j = 0; from += 1; to -= 1; for (var i = from; i < to; i += increment) { t_array[j] = [i, a[i]]; j++; } t_array.sort(function(a, b) { return comparefn(a[1], b[1]); }); var third_index = t_array[t_array.length >> 1][0]; return third_index; } var QuickSort = function QuickSort(a, from, to) { var third_index = 0; while (true) { // Insertion sort is faster for short arrays. if (to - from <= 10) { InsertionSort(a, from, to); return; } if (to - from > 1000) { third_index = GetThirdIndex(a, from, to); } else { third_index = from + ((to - from) >> 1); } // Find a pivot as the median of first, last and middle element. var v0 = a[from]; var v1 = a[to - 1]; var v2 = a[third_index]; var c01 = comparefn(v0, v1); if (c01 > 0) { // v1 < v0, so swap them. var tmp = v0; v0 = v1; v1 = tmp; } // v0 <= v1. var c02 = comparefn(v0, v2); if (c02 >= 0) { // v2 <= v0 <= v1. var tmp = v0; v0 = v2; v2 = v1; v1 = tmp; } else { // v0 <= v1 && v0 < v2 var c12 = comparefn(v1, v2); if (c12 > 0) { // v0 <= v2 < v1 var tmp = v1; v1 = v2; v2 = tmp; } } // v0 <= v1 <= v2 a[from] = v0; a[to - 1] = v2; var pivot = v1; var low_end = from + 1; // Upper bound of elements lower than pivot. var high_start = to - 1; // Lower bound of elements greater than pivot. a[third_index] = a[low_end]; a[low_end] = pivot; // From low_end to i are elements equal to pivot. // From i to high_start are elements that haven't been compared yet. partition: for (var i = low_end + 1; i < high_start; i++) { var element = a[i]; var order = comparefn(element, pivot); if (order < 0) { a[i] = a[low_end]; a[low_end] = element; low_end++; } else if (order > 0) { do { high_start--; if (high_start == i) break partition; var top_elem = a[high_start]; order = comparefn(top_elem, pivot); } while (order > 0); a[i] = a[high_start]; a[high_start] = element; if (order < 0) { element = a[i]; a[i] = a[low_end]; a[low_end] = element; low_end++; } } } if (to - high_start < low_end - from) { QuickSort(a, high_start, to); to = low_end; } else { QuickSort(a, from, low_end); from = high_start; } } }; InsertionSort([1, 2, 3, 4, 5], 0, 5); //QuickSort is recursive and calls Insertion sort, so you'll have multiple logs for this one QuickSort([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 0, 13); //You'll see that for arrays bigger than 10, QuickSort is called. var srt = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13].sort(function() { return -1 }) console.log(srt)
And JavaScriptCore uses merge sort. JavaScriptCore使用合并排序。 You can find this algorithm here: http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js
你可以在这里找到这个算法: http : //trac.webkit.org/browser/trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js
function min(a, b) { return a < b ? a : b; } function merge(dst, src, srcIndex, srcEnd, width, comparator) { var left = srcIndex; var leftEnd = min(left + width, srcEnd); var right = leftEnd; var rightEnd = min(right + width, srcEnd); for (var dstIndex = left; dstIndex < rightEnd; ++dstIndex) { if (right < rightEnd) { if (left >= leftEnd || comparator(src[right], src[left]) < 0) { dst[dstIndex] = src[right++]; continue; } } dst[dstIndex] = src[left++]; } } function mergeSort(array, valueCount, comparator) { var buffer = []; buffer.length = valueCount; var dst = buffer; var src = array; for (var width = 1; width < valueCount; width *= 2) { for (var srcIndex = 0; srcIndex < valueCount; srcIndex += 2 * width) merge(dst, src, srcIndex, valueCount, width, comparator); var tmp = src; src = dst; dst = tmp; } if (src != array) { for (var i = 0; i < valueCount; i++) array[i] = src[i]; } return array; } console.log(mergeSort([1, 2, 3, 4, 5], 5, function() { return -1; }))
Again these may not be exactly the functions used in each browser, but it shows you how different algorithms will behave if you don't actually compare values. 同样,这些可能并不完全是每个浏览器中使用的函数,但它会向您展示如果您实际上不比较值,不同算法的行为方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.