首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >铬Array.sorting号码坏掉了

铬Array.sorting号码坏掉了
EN

Stack Overflow用户
提问于 2017-04-22 19:59:27
回答 5查看 645关注 0票数 1

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

在使用CodePen几个小时之后,我意识到如果一个数组的长度是10个或更多项,Chrome将对这些项进行无序排序,至少使用这个比较函数:

代码语言:javascript
复制
var array = [0,1,2,3,4,5,6,7,8,9,10];
array.sort(function(a, b) {
        return -1;
});

Chrome返回:

代码语言:javascript
复制
[0, 2, 3, 4, 1, 6, 7, 8, 9, 10, 5]

见CodePen

如果在排序函数中记录a和b,就会发现发生这种情况的原因--这只是Chrome使用的算法。我知道人们会用退货.但让我们转到以下函数..。数组由包含div的jQuery对象组成。如果a在b的下方或左边,我想让a在b之前。有什么帮助吗?

编辑:针对这里的一些答案,我重写函数输出1-10。尽管如此,我还是得到了不想要的结果。看看如何在输出中,第一个对象的right属性大于第二个对象的left属性,而第一个对象的top属性小于第二个对象的bottom。根据比较函数,它们应该是相反的顺序。

代码语言:javascript
复制
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

代码语言:javascript
复制
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);
        });
    }
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-04-22 20:02:49

您的比较函数必须返回:

  • 否定:当第一个元素应该在第二个元素之前出现时
  • 零:当元素之间的顺序不重要时
  • 积极:当第二个元素应该出现在第一个元素之前。

返回总是-1会导致随机结果。

恐怕不可能做您想要做的事情,因为比较函数必须通过数组中的所有元素保持一致。使用您正在使用的比较函数,可以使用f(a, b) = -1f(b, a) = -1,这是不一致的:ab应该放在第一位。

票数 1
EN

Stack Overflow用户

发布于 2017-04-22 20:04:37

编辑

你原来的问题似乎过于简单化了。以下是最新的答案:

如果a在b的下方或左边,我想让a在b之前。有什么帮助吗?

在这种情况下,请确保比较每个对象的相同边缘--即比较a.leftb.lefta.bottomb.bottom .

代码语言:javascript
复制
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 } ]

原始答案

我确信这个问题已经在这个站点的其他地方得到了回答,但是您的比较器必须返回-101值才能得到预期的结果

  • -1a移动到b的左侧
  • 1a移动到b的右侧
  • 0既不会导致ab的位置变化

代码语言:javascript
复制
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 ]

或者使用超级简洁但难以读懂的链式三值表达式。

代码语言:javascript
复制
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)等等。

代码语言:javascript
复制
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 ]

票数 2
EN

Stack Overflow用户

发布于 2017-04-22 22:59:31

对不起,在我匆忙的时候,我可能没有彻底解释。得到的数组唯一需要的是,如果一个框完全高于或位于另一个数组的右侧 (a.bottom < b.top || a.left > b.right) 它应该在另一个盒子后面。

一组条件是

代码语言:javascript
复制
a.bottom < b.top || a.left > b.right ? 1 : -1

.reduceRight()调用验证。

代码语言:javascript
复制
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});

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43563981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档