JavaScript - 按位置对对象进行排序(左,上)

JavaScript - sort objects by position (left, top)

本文关键字:排序 位置 对象 JavaScript      更新时间:2023-09-26

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

数组"项目"是:

[{
    "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:

按 x,y 排序

我想

我现在明白你想实现的目标了,

我不确定使用 .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);

小提琴示例

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

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

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

如果要对重叠的框进行排序,并且要尝试为 z 索引制定一致的模式,则尤其如此。

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