Javascript,找到网格

时间:2016-07-19 19:35:35

标签: javascript lodash

我有一个带有x和y co-orditantes的项目的网格。我正在尝试编写一个函数(使用lodash)来确定第一个位置最顶部位置的第一个空位。

我试图通过迭代每个点来做到这一点,直到找到第一个空位。它只是一个2列的布局,所以我用这样的模式来处理它们 - 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
}];

以下是我一直在玩弄的小提琴:https://jsfiddle.net/alexjm/ugpy13xd/38/

我似乎无法正确理解这一逻辑,我不确定这一点我错了。任何投入将不胜感激!

正如注意:使用提供的数据,它应该将第一个空白空间标识为x:1,y:0,但是现在它说的是0 0处的空白点,这可能是不正确的。谢谢!

3 个答案:

答案 0 :(得分:2)

对于2D阵列,可以使用x + y * width计算1D索引。如果我们然后对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"
  };
}

var items = [{x:0,y:0},{x:0,y:4},{x:0,y:1},{x:0,y:2}];

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"
  };
}

document.getElementById('btn').onclick = function() {
  var space = findEmptySpace(items, 2);
  items.push(space);
  console.log(space);
};
#btn { font-size: 14pt }
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
<button id="btn">Fill the Empty Space</button>

如果对数组进行预排序,那么解决方案将是最坏情况的O(n)。

答案 1 :(得分:1)

我建议检查点是否存在与检查是否不存在。迭代列表中的每个项目,看它是否存在,如果它确实设置了标志,然后通过网格增加位置。请记住,这不会导致coords小于你的初始值&#34; startY&#34;。请考虑以下代码:

var xPlace;
var yPlace;

$(document).mousemove(function(eventParent) {
    xPlace = eventParent.pageX;
    yPlace = eventParent.pageY;
});

$(document).keydown(function(event) {
    if (event.keyCode == 109) {
        $("body").addClass("accessibility_cursordetect");
        var cursorDetect = '<div class="accessibility_cursordetect_img"></div>';
        $(cursorDetect).appendTo("body");
        $(".accessibility_cursordetect_img").css({
            "top": yPlace,
            "right": xPlace
        });
    }
});

答案 2 :(得分:0)

看起来你总是会在0,0找到一个匹配项,因为你的逻辑发现列表中的是否有任何项目不在0,0 上,而是如果是0,0

列表中的项目

您真正想做的是在当前x,y找到项目后停止检查(另外,检查两者 x和{{1在你的y中。您可以使用现有的例程和现有的isMatch支票:

isFilled