我有一个带有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处的空白点,这可能是不正确的。谢谢!
答案 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