Javascript,查找网格中的第一个空白点

Javascript,查找网格中的第一个空白点,javascript,lodash,Javascript,Lodash,我有一个网格,里面有x和y坐标。我试图编写一个函数(使用lodash)来确定第一个空点的位置,其中最左上方的点是第一个位置 我试图通过迭代每个点来实现这一点,直到找到第一个空点。这只是一个2列布局,所以我以类似于so-x:0,y:0->x:1,y:0->x:0,y:1->x:1,y:1的模式处理它们。。。然后检查沿途的所有项目,看看是否有匹配项,这样我就知道是否有空缺。我的尝试看起来是这样的: function fillEmptySpace(isFilled, startX, startY)

我有一个网格,里面有x和y坐标。我试图编写一个函数(使用lodash)来确定第一个空点的位置,其中最左上方的点是第一个位置

我试图通过迭代每个点来实现这一点,直到找到第一个空点。这只是一个2列布局,所以我以类似于so-x:0,y:0->x:1,y:0->x:0,y:1->x:1,y:1的模式处理它们。。。然后检查沿途的所有项目,看看是否有匹配项,这样我就知道是否有空缺。我的尝试看起来是这样的:

  function fillEmptySpace(isFilled, startX, startY) {
  if (!isFilled) {
    _.forEach(items, function(item, i) {
      if (!_.isMatch(item, {
          'x': startX
        }) && !_.isMatch(item, {
          'y': startY
        })
        ) {
        console.log("empty spot at", startX, startY);
        isFilled = true;
      } else if (!_.isMatch(item, {
          'x': startX + 1
        }) && !_.isMatch(item, {
          'y': startY
        })) {
        console.log("empty spot at", startX + 1, startY);
        isFilled = true;
      }
    });

    startY += 1;
    fillEmptySpace(isFilled, startX, startY);
  }
}

fillEmptySpace(false, 0, 0);
数据如下所示:

  var items = [{
  i: 'a',
  x: 0,
  y: 0,
  w: 1,
  h: 1,
  maxW: 2
}, {
  i: 'b',
  x: 1,
  y: 4,
  w: 1,
  h: 1,
  maxW: 2
}, {
  i: 'c',
  x: 0,
  y: 1,
  w: 1,
  h: 1,
  maxW: 2
}, {
  i: 'd',
  x: 0,
  y: 2,
  w: 1,
  h: 1,
  maxW: 2
}];
这是我一直在玩的小提琴:

我似乎不能完全正确地理解这一逻辑,我不确定这一点我错在哪里。任何意见都将不胜感激


需要注意的是:根据提供的数据,它应该将第一个空格标识为x:1,y:0,但是现在它表示的是0处的空位,这是不正确的。谢谢

看起来您总是会在
0,0
上找到匹配项,因为您的逻辑是查找列表中是否有不在0,0上的项,而不是列表中是否有不在0,0上的项

您真正想做的是在当前的
x,y
中找到一个项目后停止检查(此外,在
isMatch
中同时检查
x
y
)。您可以使用现有例程和现有的
isFilled
检查:

function fillEmptySpace(isFilled, startX, startY) {
  _.forEach(items, function(item, i) {
    if (!isFilled) {
      if (!_.isMatch(item, {'x': startX, 'y': startY})) {
        console.log("empty spot at", startX, startY);
        isFilled = true;
      } else if (!_.isMatch(item, {'x': startX + 1, 'y': startY})) {
        console.log("empty spot at", startX + 1, startY);
        isFilled = true;
      }
    }
  });

  if (!isFilled) {
    startY += 1;
    fillEmptySpace(isFilled, startX, startY);
  }
}

对于二维阵列,可以使用
x+y*width
计算一维索引。如果我们对1D索引进行排序,我们可以创建一个O(nlogn)解决方案:

function findEmptySpace(grid, width) {
  var index = _(grid)
    .map(function(p) { return p.x + p.y * width })
    .sortBy()
    .findIndex(_.negate(_.eq));
  if (index < 0) index = grid.length;
  return {
    x: index % width,
    y: index / width >> 0 // ">> 0" has the same result as "Math.floor"
  };
}


填补空白
我可以建议检查点是否存在,还是检查点是否存在。迭代列表中的每个项目,查看它是否存在(如果它设置了标志),然后在网格中增加位置。请记住,这并不能说明coords小于您的初始“startY”值。考虑下面的代码:

 function findEmptySpace(startX, startY) {
   var isFilled = false;
    _.forEach(items, function(item, i) {
      if (_.isMatch(item, { 'x': startX }) && _.isMatch(item, { 'y': startY }) {
        // this spot is filled check next x
        isFilled = true;
        continue;
    }
  }

  if (isFilled == true) {
    // we need to recursively call our function but I don't know the value of x
    (startX == 0) ? findEmptySpace(1, startY): findEmptySpace(0, startY + 1);
  } else {
    console.log("Congrats, we found a spot", startX, startY);
  }
}

你的网格大小是多少?@IsmailRBOUH它有2列和无限行-现在它最多可能有6行,但它可以扩展。请告诉我如何改进这个问题或我问错了什么?总是
h
w
等于1吗?@IsmailRBOUH不,这些项目上的所有属性都可以更改,这就是为什么我试着用isMatch只看x和y,然后做一个比较这似乎不起作用。当前实现最终坚持只“查找”原始数据集中已经存在的
{x:0,y:1}
;网格的行数应该是无限的,这样它就不会被卡住。此外,将测试数据的最后一项y更改为
20
甚至更早,在第四次尝试时,在返回
{x:1,y:2}
@rgthree Nice catch时卡住了!那是一只狡猾的虫子。显然,
.sort()
实际上不是lodash的一部分,所以它使用字符串进行奇怪的强制转换。现在已修复
.sortBy()
不确定为什么有人会在没有评论的情况下投票否决;那太不礼貌了。此外,我的答案不仅对OPs例程进行了最小的更改,而且后面的建议还考虑了每个项目的宽度和高度(假设OP是指它们的原始
w
h
值),这是其他答案都没有做到的。嗯,可能只是您在不加速的情况下修复了它们的代码。这仍然是一个O(n^2)实现,因为它必须查看每个索引的所有对象。除此之外,它主要阐述了OP不需要帮助的部分问题。@4公平地说,OP只是问如何修正自己的逻辑以获得所需的输出,而不是如何加快他的日常工作,这正是我“超出范围”的回答。虽然我喜欢你的优化,并且认为这应该是认可的答案,你的速度重构和我的第二部分都包含了一个项目宽度/高度,超出了OP的要求。由于我的回答没有错误,而且确实超出了范围,所以否决票是毫无根据的;尤其是在没有注释的情况下。@rgthree我认为您的第一句话非常不准确,“看起来逻辑是确定是否有任何项不在0,0上,当然,您总是有一个块不在0,0上”。列表中的第一项位于0,0,这意味着0,0上始终有一个块。真正的问题是OP正在检查他们传入的x,y是否匹配项列表中的每个项,并返回列表中第一个不匹配的项,即0,0。话虽如此,我认为任何有效的解决方案都不应该被否决,最好是在评论中接受建设性的批评。@dspano我的意思是我原来所说的,但措辞可能会更好。最初的短语的意思是“你总是有一个块[在列表中]不在0,0上”,而不是说0,0上没有块。(当然,对于只包含一个位于0,0上的块的不同数据集,这不一定是真的,但它在提供的数据集之外。)。我将改写开头以更好地解释这个场景。谢谢