我有对象的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,指定到下一张地图的门。
因此,我们有一个循环迭代4次,并在以下情况进行循环:
coords: { x: 2, y: 42 }
coords: { x: 6, y: 5 }
coords: { x: 9, y: 4 }
coords: { x: 2, y: 1 }
最后一次循环迭代将下一个映射视为mapsOrder
数组的第一个。我尝试自己先确定下一张地图的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
答案 0 :(得分:5)
如果您不关心原始数组,则只需使用shift
即可获得下一个门(shift
将从阵列中删除该门,因此当对象位于再次遇到)。使用find
从数组中查找对象:
let result = mapsOrder.map(id =>
mapData.find(o => o.id == id).gates.shift().coords
);
在使用find
之前,您可能想检查shift
是否确实找到了东西,并且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
});
答案 1 :(得分:2)
如果按照您的描述,您的循环应类似于。似乎您想使用id
和toId
但要使用数组索引。用对象替换数组是一个好主意。
for(let i = 0; i < mapsOrder.length; i++) {
let nextMap;
let currentMapId = mapsOrder[i];
if(i === mapsOrder.length - 1) {
nextMapId = mapsOrder[0]
} else {
nextMapId = mapsOrder[i + 1];
}
let filteredMapData = mapData.filter(f => f.id == currentMapId);
let filteredGates = filteredMapData.length > 0 ? filteredMapData[0].gates.filter(f => f.toId == nextMapId) : [];
console.log('Current map is: ', currentMapId, 'and the next map id is:', nextMapId, 'gates:', filteredGates.length == 0 ? "no gates": filteredGates[0].coords)
console.log('break----')
}
答案 2 :(得分:0)
我建议对JavaScript数组使用filter()
函数,因为它非常快捷。此函数将返回一个数组,该数组将填充符合某些条件的原始项目(在这种情况下,对象具有所需的ID)。
for (let i = 0; i < mapsOrder.length; i++) {
console.log(mapData.filter(mapDataItem => mapDataItem.id === mapsOrder[i]))
}