2017-04-22 88 views
1

我試圖對一個div數組進行排序,因此如果a低於或位於b的左邊,則a位於b之前。Chrome Array.sorting數字出現故障

在CodePen幾個小時後,我意識到,如果陣列的長度爲10個或更多的項目,Chrome將物品出的順序進行排序,至少與該比較功能:

var array = [0,1,2,3,4,5,6,7,8,9,10]; 
array.sort(function(a, b) { 
     return -1; 
}); 

鉻返回:

[0, 2, 3, 4, 1, 6, 7, 8, 9, 10, 5] 

See on CodePen

如果你登錄a和b的排序函數內部,它爲什麼會發生變得很明顯 - 它只是算法使用的Chrome秒。我知道人們使用return a-b等......但是讓我們來看下面的函數......該數組是包含div的jQuery對象。如果a位於b的下方或左側,我想要a來到b之前。任何幫助?

編輯:爲了迴應這裏的一些答案,我重寫函數輸出1,-10。不過,我得到了不想要的結果。看看在輸出中,第一個對象的right屬性大於第二個的left屬性,並且第一個對象的top屬性低於第二個的bottom。根據比較功能,它們應該是相反的順序。

var array = [ 
 
    
 
    { 
 
    bottom:1181.8854675292969, 
 
    left:23.39583396911621, 
 
    right:72.39583396911621, 
 
    top:910.8854675292969, 
 
    }, 
 
    
 
    { 
 
    bottom:1181.3750305175781, 
 
    left:78.39583587646484, 
 
    right:183.39583587646484, 
 
    top:1132.3750305175781 
 
    }, 
 
    
 
    { 
 
    bottom:1182.6042175292969, 
 
    left:189.39584350585938, 
 
    right:349.3958435058594, 
 
    top:1021.6042175292969 
 
    }, 
 
    
 
    { 
 
    bottom:1181.3750305175781, 
 
    left:355.3958435058594, 
 
    right:626.3958435058594, 
 
    top:1132.3750305175781 
 
    }, 
 
    
 
    { 
 
    bottom:1133.2292175292969, 
 
    left:355.3958435058594, 
 
    right:632.3958435058594, 
 
    top:1132.2292175292969 
 
    }, 
 
    
 
    { 
 
    bottom:1127.0208435058594, 
 
    left:78.39583587646484, 
 
    right:183.39583587646484, 
 
    top:1022.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:1127.0208435058594, 
 
    left:355.3958435058594, 
 
    right:460.3958435058594, 
 
    top:1022.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:1127.0208435058594, 
 
    left:466.3958435058594, 
 
    right:571.3958435058594, 
 
    top:1022.0208435058594, 
 
    }, 
 
    
 
    { 
 
    bottom:1016.0208435058594, 
 
    left:78.39583587646484, 
 
    right:183.39583587646484, 
 
    top:911.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:1016.2395935058594, 
 
    left:189.39584350585938, 
 
    right:515.3958435058594, 
 
    top:800.2395935058594 
 
    }, 
 
    
 
    { 
 
    bottom:1016.2395935058594, 
 
    left:521.3958740234375, 
 
    right:626.3958740234375, 
 
    top:800.2395935058594 
 
    }, 
 
    
 
    { 
 
    bottom:906.0208435058594, 
 
    left:23.39583396911621, 
 
    right:183.3958339691162, 
 
    top:801.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:794.6041870117188, 
 
    left:23.39583396911621, 
 
    right:72.39583396911621, 
 
    top:634.6041870117188 
 
    }, 
 
    
 
    { 
 
    bottom:795.0208435058594, 
 
    left:78.39583587646484, 
 
    right:183.39583587646484, 
 
    top:690.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:794.0208435058594, 
 
    left:189.39584350585938, 
 
    right:404.3958435058594, 
 
    top:689.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:794.0208435058594, 
 
    left:410.3958435058594, 
 
    right:515.3958435058594, 
 
    top:689.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:794.0208435058594, 
 
    left:521.3958740234375, 
 
    right:626.3958740234375, 
 
    top:689.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:683.3750152587891, 
 
    left:78.39583587646484, 
 
    right:183.39583587646484, 
 
    top:634.3750152587891 
 
    }, 
 
    
 
    { 
 
    bottom:684.6041870117188, 
 
    left:189.39584350585938, 
 
    right:349.3958435058594, 
 
    top:523.6041870117188 
 
    }, 
 
    
 
    { 
 
    bottom:684.6041870117188, 
 
    left:355.3958435058594, 
 
    right:570.3958435058594, 
 
    top:523.6041870117188 
 
    }, 
 
    
 
    { 
 
    bottom:629.0208435058594, 
 
    left:23.39583396911621, 
 
    right:183.3958339691162, 
 
    top:524.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:518.2395935058594, 
 
    left:23.39583396911621, 
 
    right:128.3958339691162, 
 
    top:302.2395935058594 
 
    }, 
 
    
 
    { 
 
    bottom:517.8854217529297, 
 
    left:134.39584350585938, 
 
    right:405.3958435058594, 
 
    top:246.8854217529297 
 
    }, 
 
    
 
    { 
 
    bottom:518.604175567627, 
 
    left:411.3958435058594, 
 
    right:626.3958435058594, 
 
    top:357.60417556762695 
 
    } 
 
]; 
 

 
array.sort(function(a, b) { 
 
    if(a.bottom < b.top || a.left > b.right) 
 
\t return 1; 
 
\t if(a.bottom > b.top || a.left < b.right) 
 
\t \t return -1; 
 
\t return 0; 
 
}); 
 

 
console.log(array[4],array[8]);

編輯:找到我的目的,一種解決方法。我以前forEach基於垂直,然後水平訂單中的商品進行比較,彼此增加z-index

function setTileZIndex() { 
     var $tiles = $('.grid__item__wrap'); 
     var coords = []; 
     $tiles.each(function(index) { 
      var topLeft = $(this).offset(); 
      var obj = { 
       bottom: topLeft.top + $(this).height(), 
       left: topLeft.left, 
       top: topLeft.top, 
       right: topLeft.left + $(this).width(), 
       $this: $(this), 
       z: 9999 
      }; 
      coords.push(obj); 
     }); 

     coords.forEach(function(a) { 
      coords.forEach(function(b) { 
       if (a.bottom < b.top) 
        b.z += 4; 
       if (a.left > b.right) 
        b.z += 1; 
      }) 
     }); 

     coords.forEach(function(elt) { 
      elt.$this.css('z-index', elt.z); 
     }); 
    } 
+0

提供完整的代碼,但是代碼段內,不codepen。 –

+2

請添加原始數據,您喜歡排序。 –

+0

你可以包括'coords'數組和問題的預期結果嗎? – guest271314

回答

1

你比較函數必須返回:

  • 負:當第一個元素前應來秒
  • 零:當元素之間的順序無關緊要時
  • 正值:當第二個元素應該在第一個元素之前。

始終返回-1會導致隨機結果。

恐怕不可能做你想做的事情,因爲比較函數必須在數組中的所有元素中保持一致。使用您正在使用的比較功能,可能有f(a, b) = -1f(b, a) = -1,這是不一致的:或者ab應該排在第一位。

+0

嗯所以我試着加入 'if(a.bottom> b.top || a.left

+0

我更新了我的答案,請檢查它。 –

+0

接受,因爲這將有助於爲什麼它不工作。儘管如此,我想不出一個解決方案。我想我會試着詢問每個元素的右上方有多少項,並根據它設置「z-index」。 –

2

編輯

看來你已經在你原來的問題過於簡單化了。這裏有一個更新的答案:

我想要一個來之前b如果一個是低於或在左邊的B。任何幫助?

在這種情況下,確保你比較每個對象的同一邊緣 - 即比較a.leftb.left,並且a.bottomb.bottom ...

const data = [ 
 
    { bottom:1181, left:23, right:72, top:910, }, 
 
    { bottom:906, left:23, right:183, top:801 }, 
 
    { bottom:1181, left:78, right:183, top:1132 }, 
 
    { bottom:1182, left:189, right:349, top:1021 }, 
 
    { bottom:1133, left:355, right:632, top:1132 }, 
 
    { bottom:795, left:78, right:183, top:690 }, 
 
    { bottom:1181, left:355, right:626, top:1132 }, 
 
    { bottom:1127, left:78, right:183, top:1022 }, 
 
    { bottom:1127, left:355, right:460, top:1022 }, 
 
    { bottom:1127, left:466, right:571, top:1022, }, 
 
    { bottom:1016, left:78, right:183, top:911 }, 
 
] 
 

 
data.sort((a,b) => { 
 
    if (a.left < b.left || a.bottom < b.bottom) 
 
    return -1 
 
    else if (a.right > b.right || a.top > b.top) 
 
    return 1 
 
    else 
 
    return 0 
 
}) 
 

 
console.log(data) 
 
// [ { bottom: 906, left: 23, right: 183, top: 801 }, 
 
// { bottom: 1181, left: 23, right: 72, top: 910 }, 
 
// { bottom: 795, left: 78, right: 183, top: 690 }, 
 
// { bottom: 1016, left: 78, right: 183, top: 911 }, 
 
// { bottom: 1127, left: 78, right: 183, top: 1022 }, 
 
// { bottom: 1182, left: 189, right: 349, top: 1021 }, 
 
// { bottom: 1133, left: 355, right: 632, top: 1132 }, 
 
// { bottom: 1181, left: 78, right: 183, top: 1132 }, 
 
// { bottom: 1127, left: 355, right: 460, top: 1022 }, 
 
// { bottom: 1181, left: 355, right: 626, top: 1132 }, 
 
// { bottom: 1127, left: 466, right: 571, top: 1022 } ]


原始答覆

我敢肯定這已經回答了其他地方上這個網站,但你的比較必須回報-10,並且1值來獲得預期的結果

  • -1移動a到左側b
  • 1移動ab
  • 0導致奈特神權呃ab變換位置

let sorted = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].sort((a,b) => { 
 
    if (a < b) 
 
    return -1 
 
    else if (a > b) 
 
    return 1 
 
    else 
 
    return 0 
 
}) 
 

 
console.log(sorted) 
 
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]


或者使用超簡潔,但更難閱讀的鏈接三元表達式

let sorted = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].sort((a,b) => 
 
    a < b ? -1 : a > b ? 1 : 0 
 
) 
 

 
console.log(sorted) 
 
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]


請記住,數組中的元素不一定以你所期望的訂單相比 - 也就是說,別指望compare(0,1)然後compare(1,2),然後compare(2,3)

let sorted = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].sort((a,b) => { 
 
    console.log(a,b) 
 
    return a < b ? -1 : (a > b ? 1 : 0) 
 
}) 
 
// 0 10 
 
// 0 5 
 
// 10 5 
 
// 2 5 
 
// 3 5 
 
// 4 5 
 
// 1 5 
 
// 6 5 
 
// 9 5 
 
// 8 5 
 
// 7 5 
 
// 0 2 
 
// 2 3 
 
// 3 4 
 
// 4 1 
 
// 3 1 
 
// 2 1 
 
// 0 1 
 
// 6 7 
 
// 7 8 
 
// 8 9 
 
// 9 10 
 

 
console.log(sorted) 
 
//=> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

+0

_「您的比較器必須返回」-1「,」0「和」1「值才能得到預期的結果」_您能夠準確描述「-1」,「0」和「1」結果對於答案中的'a','b'和返回數組? – guest271314

+0

雖然答案是正確的,但chrome對數組長度> = 10有不同的排序算法。chrome用於返回相同的值不穩定。 –

+0

@NinaScholz有趣。只要比較器是正確定義的,沒有突出的bug,是嗎? – naomik

0

這是一個比較功能,將爲你工作。

var arr = [15, 4, 11, 19, 11]; 
 

 
function compareFn(a, b) { 
 
    return a > b ? 1 : a === b ? 0 : -1; 
 
} 
 

 
var sorted = arr.sort(compareFn); 
 

 
console.log(sorted);

0

請測試在Chrome和例如在邊緣的代碼。在Crome中,如果所有比較的返回值都相同,則排序不穩定。

var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
 
array.sort(function(a, b) { return 0; }); 
 
console.log(array); // Chrome: [5, 0, 2, 3, 4, 1, 6, 7, 8, 9, 10] 
 
        // Edge: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
 
array.sort(function(a, b) { return 1; }); 
 
console.log(array); // Chrome: [5, 10, 0, 9, 8, 7, 6, 1, 4, 3, 2] 
 
        // Edge: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
 
array.sort(function(a, b) { return -1; }); 
 
console.log(array); // Chrome: [0, 2, 3, 4, 1, 6, 7, 8, 9, 10, 5] 
 
        // Edge: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

1

對不起,在我匆忙之餘,我可能沒有徹底解釋。結果數組所需的唯一 的事情是,如果一箱是完全 上方或另一

(a.bottom < b.top || a.left > b.right)

,它也應該在其他框後的權利。條件

一組是

a.bottom < b.top || a.left > b.right ? 1 : -1 

由​​電話覈實。

var coords = [ 
 
    
 
    { 
 
    bottom:1181.8854675292969, 
 
    left:23.39583396911621, 
 
    right:72.39583396911621, 
 
    top:910.8854675292969, 
 
    }, 
 
    
 
    { 
 
    bottom:1181.3750305175781, 
 
    left:78.39583587646484, 
 
    right:183.39583587646484, 
 
    top:1132.3750305175781 
 
    }, 
 
    
 
    { 
 
    bottom:1182.6042175292969, 
 
    left:189.39584350585938, 
 
    right:349.3958435058594, 
 
    top:1021.6042175292969 
 
    }, 
 
    
 
    { 
 
    bottom:1181.3750305175781, 
 
    left:355.3958435058594, 
 
    right:626.3958435058594, 
 
    top:1132.3750305175781 
 
    }, 
 
    
 
    { 
 
    bottom:1133.2292175292969, 
 
    left:355.3958435058594, 
 
    right:632.3958435058594, 
 
    top:1132.2292175292969 
 
    }, 
 
    
 
    { 
 
    bottom:1127.0208435058594, 
 
    left:78.39583587646484, 
 
    right:183.39583587646484, 
 
    top:1022.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:1127.0208435058594, 
 
    left:355.3958435058594, 
 
    right:460.3958435058594, 
 
    top:1022.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:1127.0208435058594, 
 
    left:466.3958435058594, 
 
    right:571.3958435058594, 
 
    top:1022.0208435058594, 
 
    }, 
 
    
 
    { 
 
    bottom:1016.0208435058594, 
 
    left:78.39583587646484, 
 
    right:183.39583587646484, 
 
    top:911.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:1016.2395935058594, 
 
    left:189.39584350585938, 
 
    right:515.3958435058594, 
 
    top:800.2395935058594 
 
    }, 
 
    
 
    { 
 
    bottom:1016.2395935058594, 
 
    left:521.3958740234375, 
 
    right:626.3958740234375, 
 
    top:800.2395935058594 
 
    }, 
 
    
 
    { 
 
    bottom:906.0208435058594, 
 
    left:23.39583396911621, 
 
    right:183.3958339691162, 
 
    top:801.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:794.6041870117188, 
 
    left:23.39583396911621, 
 
    right:72.39583396911621, 
 
    top:634.6041870117188 
 
    }, 
 
    
 
    { 
 
    bottom:795.0208435058594, 
 
    left:78.39583587646484, 
 
    right:183.39583587646484, 
 
    top:690.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:794.0208435058594, 
 
    left:189.39584350585938, 
 
    right:404.3958435058594, 
 
    top:689.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:794.0208435058594, 
 
    left:410.3958435058594, 
 
    right:515.3958435058594, 
 
    top:689.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:794.0208435058594, 
 
    left:521.3958740234375, 
 
    right:626.3958740234375, 
 
    top:689.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:683.3750152587891, 
 
    left:78.39583587646484, 
 
    right:183.39583587646484, 
 
    top:634.3750152587891 
 
    }, 
 
    
 
    { 
 
    bottom:684.6041870117188, 
 
    left:189.39584350585938, 
 
    right:349.3958435058594, 
 
    top:523.6041870117188 
 
    }, 
 
    
 
    { 
 
    bottom:684.6041870117188, 
 
    left:355.3958435058594, 
 
    right:570.3958435058594, 
 
    top:523.6041870117188 
 
    }, 
 
    
 
    { 
 
    bottom:629.0208435058594, 
 
    left:23.39583396911621, 
 
    right:183.3958339691162, 
 
    top:524.0208435058594 
 
    }, 
 
    
 
    { 
 
    bottom:518.2395935058594, 
 
    left:23.39583396911621, 
 
    right:128.3958339691162, 
 
    top:302.2395935058594 
 
    }, 
 
    
 
    { 
 
    bottom:517.8854217529297, 
 
    left:134.39584350585938, 
 
    right:405.3958435058594, 
 
    top:246.8854217529297 
 
    }, 
 
    
 
    { 
 
    bottom:518.604175567627, 
 
    left:411.3958435058594, 
 
    right:626.3958435058594, 
 
    top:357.60417556762695 
 
    } 
 
]; 
 

 

 
// a.bottom < b.top || a.left > b.right ? a.bottom > b.top || a.left < b.right ? 0 : 1 : -1 
 
coords.sort((a, b) => a.bottom < b.top || a.left > b.right ? 1 : -1); 
 

 
console.log(coords); 
 

 
coords.reduceRight((a, b) => {console.log(a.bottom < b.top || a.left > b.right); return b});

+0

當我用我的答案和我'console.log(coords [4],coords [8])'(因爲這些都是問題的)中使用的數組運行此代碼時,記錄爲: 'Object { '底部:1133.2292175292969,'' 左:355.3958435058594,'' 右:632.3958435058594,'' 頂部:1132.2292175292969' '} {對象'' 底部:1016.0208435058594,'' 左:78.39583587646484,'' 右:183.39583587646484,' 'top:911.0208435058594' '}' 相同的結果...但是由於初始數組的順序會影響輸出,所以函數一定有問題。我認爲@Thaiago Barcala正在做點什麼。 –

+0

@ nth-chile不確定你的意思。 _「結果數組唯一需要的是,如果一個盒子完全在另一個」(a.bottom b.right)「的右邊或者右邊,它應該在另一個盒子「。_(a.bottom b.right)'對於每個'a,b'都是相反的順序'',''.reduceRight()'驗證。 – guest271314