Chrome Array.sorting数字乱序

时间:2017-04-22 19:59:28

标签: javascript arrays google-chrome sorting

我试图对div数组进行排序,以便a位于b下方或左侧,a位于b之前。

在CodePen中使用了几个小时之后,我意识到如果一个数组的长度为10个或更多项,那么Chrome会不按顺序对这些项进行排序,至少使用这个比较函数:

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

Chrome返回:

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

See on CodePen

如果你在sort函数中记录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)
	  return 1;
	if(a.bottom > b.top || a.left < b.right)
		return -1;
	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);
        });
    }

5 个答案:

答案 0 :(得分:2)

修改

您的原始问题似乎过于简化了。这是一个更新的答案:

  

如果a低于或低于b,我希望a在b之前来。任何帮助?

在这种情况下,请确保您要比较每个对象的相同边缘 - 即将org.bytedeco.javacpp.opencv_imgcodecs.imreada.left进行比较,将b.lefta.bottom进行比较... < / p>

b.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
  • 的左侧
  • b1移至a
  • 的右侧
  • b不会导致0a更改职位

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)

答案 1 :(得分:1)

您的比较功能必须返回:

  • 否定:第一个元素应该在第二个元素之前
  • 零:当元素之间的顺序无关紧要时
  • 肯定:当第二个元素应该在第一个元素之前。

返回始终为-1会导致随机结果。

我担心你不可能做你想做的事情,因为比较函数必须通过数组中的所有元素保持一致。使用您正在使用的比较功能时,可能会有f(a, b) = -1f(b, a) = -1,这是不一致的:ab应该先出现。

答案 2 :(得分:1)

  

抱歉,在我的匆忙中,我可能没有彻底解释。唯一的   结果数组所需要的是,如果一个盒子是完全的   在或在另一个的右边

     

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

     

它应该在另一个盒子之后。

一组条件是

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

.reduceRight()电话验证。

&#13;
&#13;
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});
&#13;
&#13;
&#13;

答案 3 :(得分:0)

这是一个适合您的比较功能。

&#13;
&#13;
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);
&#13;
&#13;
&#13;

答案 4 :(得分:0)

请在Chrome中测试代码,例如在Edge中。在Crome中,如果所有比较的返回值相同,则排序不稳定。

&#13;
&#13;
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];
&#13;
&#13;
&#13;

&#13;
&#13;
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];
&#13;
&#13;
&#13;

&#13;
&#13;
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]
&#13;
&#13;
&#13;