[英]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.