[英]Pairwise remove elements from array
我想要一个函数( collisions
),当它们太相似时可以从数组中删除对象。 我有一个工作版本,但它太丑了,我不想提交。
在我的 10x10 游泳池中,我有很多船:
var boats = [
{name: "A", position: [1,1] }, // collides with E and G
{name: "B", position: [7,8] }, // collides with D
{name: "C", position: [8,2] }, // will not collide
{name: "D", position: [7,9] }, // collides with B
{name: "E", position: [2,1] }, // collides with A and G
{name: "F", position: [1,7] }, // will not collide
{name: "G", position: [2,2] }, // collides with A and E
]
船只需要小心不要靠近其他船只。
const collisionDistance = 5;
function distance(boat1, boat2) {
return Math.sqrt(
Math.pow(boat1.position[0] - boat2.position[0], 2) +
Math.pow(boat1.position[1] - boat2.position[1], 2)
);
}
如果他们不这样做,两艘船都会沉没。 (这是需要重构的部分)
// Boats that are too close to another boat are removed from the list of boats
// How can I make this beautiful?
function collisions() {
var collidingBoatIndices = new Set();
// iterate over pairs of the list
for (let i = 0; i < boats.length; i++) {
for (let j = i+1; j < boats.length; j++) {
if (distance(boats[i], boats[j]) < collisionDistance) {
collidingBoatIndices.add(i);
collidingBoatIndices.add(j);
}
}
}
// delete from biggest to smallest index so there is no shift in the elements
for (let index of Array.from(collidingBoatIndices).sort().reverse()){
console.log("Boat sank: ", boats[index])
boats.splice(index, 1);
}
}
在上面的设置中,我希望只有船C
和F
能够生存。
console.log("Boats at start:", boats.map((boat => boat.name)));
collisions()
console.log("Boats left over:", boats.map((boat => boat.name)));
所以我的问题是:如何让函数collisions
更简单、更易读?
我不明白你为什么要保存索引而不是船......检查这个:
var boats = [ {name: "A", position: [1,1] }, // collides with E and G {name: "B", position: [7,8] }, // collides with D {name: "C", position: [8,2] }, // will not collide {name: "D", position: [7,9] }, // collides with B {name: "E", position: [2,1] }, // collides with A and G {name: "F", position: [1,7] }, // will not collide {name: "G", position: [2,2] }, // collides with A and E ] const collisionDistance = 5; function distance(boat1, boat2) { return Math.sqrt( Math.pow(boat1.position[0] - boat2.position[0], 2) + Math.pow(boat1.position[1] - boat2.position[1], 2) ); } const res = [] for(let i = 0; i < boats.length ; i++){ let flag = true; for(let j = 0; j < boats.length; j++){ if(distance(boats[i], boats[j]) < collisionDistance && i != j){ flag = false; } } if(flag){ res.push(boats[i]) } } console.log( res )
但是您可以采用一种更具可读性的功能方式,如下所示:
var boats = [ {name: "A", position: [1,1] }, // collides with E and G {name: "B", position: [7,8] }, // collides with D {name: "C", position: [8,2] }, // will not collide {name: "D", position: [7,9] }, // collides with B {name: "E", position: [2,1] }, // collides with A and G {name: "F", position: [1,7] }, // will not collide {name: "G", position: [2,2] }, // collides with A and E ] const collisionDistance = 5; function distance(boat1, boat2) { return Math.sqrt( Math.pow(boat1.position[0] - boat2.position[0], 2) + Math.pow(boat1.position[1] - boat2.position[1], 2) ); } const res = boats.filter( (b1, i) => boats.every( (b2, j) => !(distance(b1, b2) < collisionDistance && i != j) ) ) console.log(res)
正如@pilchard指出的,您可以通过使用some
来提高性能(即使在 10x10 的工作表中您不会看到这样的改进):
var boats = [ {name: "A", position: [1,1] }, // collides with E and G {name: "B", position: [7,8] }, // collides with D {name: "C", position: [8,2] }, // will not collide {name: "D", position: [7,9] }, // collides with B {name: "E", position: [2,1] }, // collides with A and G {name: "F", position: [1,7] }, // will not collide {name: "G", position: [2,2] }, // collides with A and E ] const collisionDistance = 5; function distance(boat1, boat2) { return Math.sqrt( Math.pow(boat1.position[0] - boat2.position[0], 2) + Math.pow(boat1.position[1] - boat2.position[1], 2) ); } const res = boats.filter( (b1, i) => !boats.some( (b2, j) => distance(b1, b2) < collisionDistance && i != j ) ) console.log(res)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.