javascript - 通过 mapsOrder 数组确定下一张 map

标签 javascript arrays algorithm

我有 mapsOrder 数组和 mapsData 对象数组:

let mapsOrder = [1,2,1,3];
let mapData = [
  {
    id: 1,
    gates: [
      {
        toId: 2,
        coords: {
          x: 2,
          y: 42
        }
      },
      {
        toId: 3,
        coords: {
          x: 9,
          y: 4
        }
      }
    ]
  },
  {
    id: 2,
    gates: [
      {
        toId: 1,
        coords: {
          x: 6,
          y: 5
        }
      }
    ]
  },
  {
    id: 3,
    gates: [
      {
        toId: 1,
        coords: {
          x: 2,
          y: 1
        }
      }
    ]
  }
]

我想要实现的是基于 mapsOrder 的循环,其中 mapsOrder 数组值是 mapData 中的 id,指定下一张 map 的门。

所以我们有循环迭代 4 次以及何时:

  • 循环索引为 1 当前 map 为 1 下一张 map 为 2 下一张 map 为 coords: { x: 2, y: 42 }
  • 循环索引为 2 当前 map 为 2 下一张 map 为 1 下一张 map 为 坐标:{ x: 6, y: 5 }
  • 循环索引为 3 当前 map 为 1 下一张 map 为 3 下一张门为 坐标:{ x: 9, y: 4 }
  • 循环索引为 4 当前 map 为 3 下一个 map 为 1 下一个 map 为 coords: { x: 2, y: 1 }

最后一个循环迭代将下一个 map 视为 mapsOrder 数组的第一个。我试着自己做,首先像这样确定下一张 map 的 ID:

for(let i = 0; i < mapsOrder.length; i++) {
  let nextMap;
  let currentMapId = mapData[mapsOrder[i] - 1].id;
  if(i === mapsOrder.length - 1) {
    nextMap = mapData[0].id   
  } else {
    nextMapId = mapData[mapsOrder[i]].id;    
  }

  console.log('Current map is: ', currentMapId, 'and the next map id is:', nextMapId)
  console.log('break-----')

}

但是这个控制台的 ID 不正确,demo

最佳答案

如果您不关心原始数组,则只需使用 shift 获取下一个门(shift 将从数组中删除门,因此下一个门将再次遇到该对象时可用)。使用 find 从数组中查找对象:

let result = mapsOrder.map(id =>
    mapData.find(o => o.id == id).gates.shift().coords
);

在使用 shift 之前,您可能需要检查 find 是否真的找到了一些东西并且 gates 数组包含一些东西,这是一种更安全的方法:

let result = mapsOrder.map(id => {
    let obj = mapData.find(o => o.id == id);
    if(obj && obj.gates.length) {                  // if we found an object with the same id and that object still have gates
        return obj.gates.shift().coords;           // return the coords of the first gate and remove the gate from the array
    }                                              // otherwise, throw an error or something
});

不改变:

我们不再使用前面示例中的 shift,而是使用一个对象来跟踪 gates 数组中的门索引:

let nextGateIndex = Object.create(null);                             // create a prototypeless object to track the next gate index for each object
let result = mapsOrder.map(id => {
    let obj = mapData.find(o => o.id == id);
    let index;
    if(nextGateIndex[id] == undefined) {
        index = 0;
    } else {
        index = nextGateIndex[id] + 1;
    }
    nextGateIndex[id] = index;
    if(obj && index < obj.gates.length) {
        return obj.gates[index].coords;
    }                                                                // throw error or something
});

关于javascript - 通过 mapsOrder 数组确定下一张 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55755090/

相关文章:

php - CSS + jQ 插件阻止 AJAX 调用/事件监听器工作?

java - 如何使用 Rectangle 类创建矩形数组?

java - 如何将多个单个数组连接成一个大的单个数组

Javascript - 有条件地选择 while 循环的条件

c++ - 为什么要用堆来存储内存?

python - 从python中的权重数组中获取随机索引的快速方法

javascript - 将 Font Awesome 图标设置为 jquery

javascript - 调用全局函数且无法返回定义的变量

python - "map"的算法

javascript - 是什么导致无法检测到此 Vue 3 应用程序中 html 元素外部的单击事件?