Javascript,查找网格中的第一个空白点
我有一个网格,里面有x和y坐标。我试图编写一个函数(使用lodash)来确定第一个空点的位置,其中最左上方的点是第一个位置 我试图通过迭代每个点来实现这一点,直到找到第一个空点。这只是一个2列布局,所以我以类似于so-x:0,y:0->x:1,y:0->x:0,y:1->x:1,y:1的模式处理它们。。。然后检查沿途的所有项目,看看是否有匹配项,这样我就知道是否有空缺。我的尝试看起来是这样的: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)
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上的块的不同数据集,这不一定是真的,但它在提供的数据集之外。)。我将改写开头以更好地解释这个场景。谢谢