【问题标题】:JavaScript - sort objects by position (left, top)JavaScript - 按位置(左,上)对对象进行排序
【发布时间】:2020-11-08 00:36:51
【问题描述】:

我有一个代表页面上 div 元素位置的对象数组。该数组未排序,我需要对其进行排序,以便它们按从左到右然后从上到下的顺序排列。

数组“items”是:

[{
    "id": "Box 2",
    "x": 354,
    "y": 6
},
{
    "id": "Box 3",
    "x": 15,
    "y": 147
},
{
    "id": "Box 1",
    "x": 12,
    "y": 12
},
{
    "id": "Box 4",
    "x": 315,
    "y": 146
}]

我试过按 x 排序:

items.sort(function(a, b){
if (a.x == b.x) return a.y - b.y;
    return a.x - b.x || a.y - b.y;
});

和/或按 y 排序:

items.sort(function(a, b){
    if (a.y == b.y) return a.x - b.x;
    return a.y - b.y;
});

项目分别按x或y排序,但我希望它们排列成数组排序为box1、box2、box3、box4:

Sorted by x,y

【问题讨论】:

  • 你不应该考虑盒子的宽度和高度吗?
  • 这些框是在 UI 中通过将它们拖放到页面上来创建的,因此它们将由用户定位。如果它们重叠,那就是用户想要的。每个 div(即框)都使用绝对位置,因此内部不会影响布局,但是我需要从左到右然后从上到下对它们进行排序,所以我最终得到一个看起来像的数组顺序图片。
  • 如果要先从左到右,为什么box2在box3之前?顺序为:box1、box3、box4、box2
  • 这是不可能的,因为数组包含的是点,而不是框。您可以按点排序,然后结果将是 box2, box1, box3, box4

标签: javascript arrays sorting


【解决方案1】:

我想我现在明白你想要达到的目标了,

我不确定 .sort 选项是否可行,我可能错了。

这是基于双索引比较和标记以标记已添加框的工作代码。

var arranged = [];
var items = [{
  "id": "Box 2",
  "x": 354,
  "y": 6
}, {
  "id": "Box 3",
  "x": 15,
  "y": 147
}, {
  "id": "Box 1",
  "x": 12,
  "y": 12
}, {
  "id": "Box 4",
  "x": 315,
  "y": 146
}]

items.sort(function(a, b) {
  //sort by x, secondary by y
  return a.x == b.x ? a.y - b.y : a.x - b.x;
});
console.log(items);


for (var i = 0; i < items.length; i++) {

  //check if was already added
  if (typeof(items[i].wasAdded) == "undefined") {
    arranged.push(items[i]);
    items[i].wasAdded = "true";

    for (j = i + 1; j < items.length; j++) {
      if (items[i].y > items[j].y && typeof(items[j].wasAdded) == "undefined") {
        arranged.push(items[j]);
        items[j].wasAdded = "true";
      }
    }
  }
}
console.log(arranged);

fiddle example

【讨论】:

    【解决方案2】:

    在尝试解决一个非常相似的问题时来到这里。这是我的结论:

    除非您的项目在网格中,否则您可能实际上不希望按照您描述的方式对它们进行排序,从上到下然后从左到右。相反,您可能希望根据它们与左上角的距离对它们进行排序。

    boxes.sort((a, b) => Math.hypot(a.x, a.y) - Math.hypot(b.x, b.y))
    

    如果您正在对重叠的框进行排序并且您正在尝试为 z-index 制定一致的模式,则尤其如此。

    boxes
      .sort((a, b) => Math.hypot(a.x, a.y) - Math.hypot(b.x, b.y))
      .forEach((box, i) => box.z = i)
    

    【讨论】:

      猜你喜欢
      • 2011-11-16
      • 2023-02-05
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 2011-10-04
      • 2016-12-23
      • 2016-07-09
      相关资源
      最近更新 更多