2017-04-22 8 views
1

abの下または左にある場合、abの前になるように、divの配列を並べ替えようとしていました。Chrome Array.sorting numbers out of order

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

あなたはログインしている場合、それがなぜ起こるかbがソート関数の内部で、それが明らかになった - それだけで、アルゴリズムのクロムの使用ですs。私は人々がリターンa-bなどを使用することを知っていますが、次の関数に回しましょう...配列はdivを含むjQueryオブジェクトです。 aがbの下か左にあるなら、aの前に来てほしい。どんな助け?

EDIT:ここでの答えに応じて、1-1、または0のいずれかを出力する関数を書き換えます。それでも、私は望ましくない結果を得る。出力では、最初のオブジェクトのrightプロパティが2番目のleftプロパティよりも大きく、最初のオブジェクトのtopプロパティが2番目の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]);

EDIT:私の目的のために回避策を見つけました。私はお互いにアイテムを比較し、垂直方向と、水平順序に基づいてz-indexをインクリメントするforEachを使用:

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'配列と期待される結果をQuestionに含めることができますか? – guest271314

答えて

1

あなたの比較関数が返す必要があります。

  • 負:最初の要素の前に来るべき時second
  • ゼロ:要素間の順序が重要でない場合
  • ポジティブ:2番目の要素が最初の要素の前に来るとき。

常に-1を返すと、ランダムな結果が返されます。

compare関数が配列内のすべての要素を通じて一貫していなければならないので、これを行うことはできません。使用している比較機能では、f(a, b) = -1f(b, a) = -1の間に矛盾があります。aまたはbのいずれかが先に来る必要があります。

+0

だから私は追加しようとしました 'if(a.bottom> b.top || a.left

+0

私の答えが更新されましたので、確認してください。 –

+0

なぜこれが機能していないのかがわかります。私は解決策を考えることはできません。私は各要素の右上に_how many itemsがあることを尋ねようと思うし、それに基づいて 'z-index'を設定します。 –

2

EDIT

あなたの元の質問に過剰に簡略化しましたようです。更新された答えは次のとおりです。

もしaがbの下または左にあるならば、前に来て欲しいです。どんな助け?その場合

、あなたが各オブジェクトの同じエッジを比較していることを確認してください - すなわちb.lefta.leftを比較し、b.bottoma.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 } ]


元の回答

私は、これは、このサイト上で他のどこか回答されている確信しているが、あなたのコンパレータの左にaを移動-1

  • 意図した結果を得るために-10、および1値を返す必要がありますb
  • 1はネイトでb
  • 0結果の右側にaを移動させますえーaまたはb変更箇所

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興味深い。コンパレータが適切に定義されている限り、未解決のバグはありませんか? – 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)

の真上ORのであれば、ということです。​​呼び出しによって検証などの条件の

1つのセットは

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)の右側にORの上にある場合、それは'.reduceRight()'が検証するので ''(a.bottom b.right) 'は' a、b'の逆順で 'true ' 。 – guest271314