J'ai un tableau mapsOrder et un tableau mapsData d'objets:
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-----')
}
Ce que je veux réaliser est en boucle basée sur mapsOrder où mapsOrder code > les valeurs du tableau sont des identifiants dans mapData , désignent les portes de la carte suivante.
Nous avons donc une boucle qui itère 4 fois et quand:
coordonnées: {x: 2, y: 42} coordonnées: {x: 6, y: 5} coords: {x: 9, y: 4} coords: {x: 2, y: 1} dernière itération de boucle voir la carte suivante comme première du tableau mapsOrder . J'ai essayé de le faire moi-même en déterminant d'abord l'id de la prochaine carte comme ceci:
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
}
}
]
}
]
mais cette console est incorrecte, démo
3 Réponses :
Je recommanderais le filter () pour les tableaux javascript car c'est super rapide. Cette fonction renverra un tableau rempli d'éléments de l'original correspondant à certains critères (dans ce cas, les objets ayant l'ID souhaité).
for (let i = 0; i < mapsOrder.length; i++) {
console.log(mapData.filter(mapDataItem => mapDataItem.id === mapsOrder[i]))
}
Mais je ne sais toujours pas dans la première et la troisième itération si je dois choisir le premier ou le deuxième objet du tableau gates .
Si vous ne vous souciez pas du tableau d'origine, utilisez simplement shift pour obtenir la porte suivante ( shift supprimera la porte du tableau donc la prochaine porte sera être disponible lorsque l'objet est à nouveau rencontré). Utilisez find pour trouver l'objet dans le tableau:
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
});
Vous voudrez peut-être vérifier si find trouve réellement quelque chose et que le tableau de portes contient quelque chose avant d'utiliser shift , voici un moyen plus sûr:
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
});
Aucune modification:
Au lieu d'utiliser shift de l'exemple précédent, nous allons simplement utiliser un objet pour suivre l'index de la porte à partir du tableau portes :
let result = mapsOrder.map(id =>
mapData.find(o => o.id == id).gates.shift().coords
);
Cela va détruire les portes du tableau original d'objets, n'est-ce pas?
Oui. Vous avez dit que vous pouviez modifier le tableau d'origine. Si vous ne voulez pas le modifier, utilisez simplement un objet pour suivre le prochain index de porte. Je modifierai la réponse
Je m'en fiche pour le moment, je ne suis pas sûr de ne pas avoir besoin du tableau d'origine dans le futur code.
@ BT101 Découvrez la version sans modification. Dites-moi si vous ne comprenez pas quelque chose. Bonne chance! :RÉ
Si vous suivez votre description, votre boucle devrait ressembler à. Il semble que vous utilisiez id et toId mais en utilisant des index de tableau. Il peut être judicieux de remplacer les tableaux par des objets.
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----')
}
Pouvez-vous modifier le tableau d'origine et ses objets?
Oui je peux le faire.