无法访问数组的正确部分以仅提取相关信息

问题描述 投票:0回答:2

我在代码中创建了一个数组,其中包含大量信息。我的问题可能比阅读更容易回答,但由于某种原因,经过四个小时的混乱,我只是无法瞄准数组的正确部分来提取信息。第一个片段是该数组的截断输出,

fullTerritoriesInRange
或足够让我继续我的问题:

[
    [
        [
            "7",
            "Vatican City"
        ],
        [
            [
                "Italy",
                [
                    {
                        "x": 1311.7569580078126,
                        "y": 156.45799255371095
                    }, //etc etc
                ],
                0.8130994663446266
            ],
            [
                "Corsica",
                [
                ],
                11.270796168914153
            ],
            [
                "Sardinia",
                [
                ],
                13.191931711691217
            ],
            [
                "Croatia",
                [
                ],
                18.581217785849135
            ],
            [
                "Slovenia",
                [
                ],
                22.755208655235703
            ],
            [
                "Bosnia And Herzegovina",
                [
                ],
                24.103141314701163
            ],
            [
                "France",
                [
                ],
                24.795528021316174
            ],
            [
                "Tunisia",
                [
                ],
                27.31657280841581
            ],
            [
                "Montenegro",
                [
                    
                ],
                28.780943036642854
            ],
            [
                "Switzerland",
                [
                    
                ],
                28.824686624652168
            ]
        ]
    ]
]

该数组显示领土梵蒂冈城的名称,以及其“范围内”的所有领土(意大利等)

然后我尝试创建这个数组的副本,这基本上是相同的,除了如果该领土由玩家“拥有”,它不会在新数组中包含该领土

attackableTerritoriesInRange
,这就是我的试过了。

const attackableTerritoriesInRange = [];
        for (let j = 0; j < fullTerritoriesInRange.length; j++) {
            let isOwned = false; // Flag to track if any match is found

            for (let k = 0; k < fullTerritoriesInRange[j][1].length; k++) {
                const territoryNameToCheck = fullTerritoriesInRange[j][1][k][0];
                for (let l = 0; l < arrayOfLeadersAndCountries[i][2].length; l++) {
                    const ownedTerritoryName = arrayOfLeadersAndCountries[i][2][l].territoryName;
                    if (territoryNameToCheck === ownedTerritoryName) {
                        isOwned = true;
                        break; // No need to continue checking, one match is enough
                    }
                }
                if (isOwned) {
                    break;
                }
            }
            if (!isOwned) {
                attackableTerritoriesInRange.push(fullTerritoriesInRange[j][1]);
            }
            console.log("and the attackable territories are:");
            console.log(attackableTerritoriesInRange);
        }

代码片段中对

[i]
的任何引用均指当前正在检查其可能众多领土的玩家,即整个代码片段位于
i
循环中。这个循环是一个名为
arrayOfLeadersAndCountries
的不同数组,它保存每个 AI 玩家的所有信息。这个数组是我们知道它是否被拥有的方式,下面是该数组的输出:

[
    [
        "Vatican City",
        {
            "name": "Champion Sasha IV",
            "leaderType": "aggressive",
            "traits": {
                "dominance": 0.9527169509560709,
                "economy": 0.3240949299375549,
                "territory_expansion": 0.9349304869977676,
                "style_of_war": 0.9428410503399216,
                "reconquista": 0.35144885924449245
            }
        },
        [
            {
                "uniqueId": "7",
                "dataName": "Vatican City",
                "territoryId": "0",
                "territoryName": "Vatican City",
                "territoryPopulation": 800,
                "productiveTerritoryPop": 285.32,
                "area": 3752.993217866781,
                "continent": "Europe",
                "armyForCurrentTerritory": 7,
                "assaultForCurrentTerritory": 0,
                "useableAssault": 0,
                "airForCurrentTerritory": 0,
                "useableAir": 0,
                "navalForCurrentTerritory": 0,
                "useableNaval": 0,
                "infantryForCurrentTerritory": 7,
                "goldForCurrentTerritory": 387.9310344827586,
                "oilForCurrentTerritory": 106.01078144024904,
                "oilCapacity": 106.01078144024904,
                "oilDemand": 0,
                "foodForCurrentTerritory": 0.08070000000000001,
                "foodCapacity": 807,
                "foodConsumption": 807,
                "consMatsForCurrentTerritory": 300,
                "consMatsCapacity": 300,
                "devIndex": 0.812,
                "continentModifier": 15,
                "farmsBuilt": 0,
                "oilWellsBuilt": 0,
                "forestsBuilt": 0,
                "fortsBuilt": 0,
                "defenseBonus": 10,
                "isDeactivated": false,
                "isCoastal": false,
                "isLandLockedBonus": 10,
                "mountainDefense": 2,
                "mountainDefenseBonus": 20,
                "owner": "Vatican City",
                "leader": {
                    "name": "Champion Sasha IV",
                    "leaderType": "aggressive",
                    "traits": {
                        "dominance": 0.9527169509560709,
                        "economy": 0.3240949299375549,
                        "territory_expansion": 0.9349304869977676,
                        "style_of_war": 0.9428410503399216,
                        "reconquista": 0.35144885924449245
                    }
                }
            }
        ]
    ],

arrayOfLeadersAndCountries[i][2]
是一个具有属性
.territoryName
的对象,如果该字符串出现在正在检查的列表中,则意味着正在检查的区域是玩家拥有的领土,不应添加。

因此,将所有这些信息放在一起,如果在检查每个玩家的领土时玩家拥有可到达的领土,则应跳过,否则应将其推送到

attackableTerritoriesInRange
数组。

由于解释这个问题的复杂性,我给出了一个 AttackableTerritoriesInRange 数组应该是什么样子的示例:

在此场景中,当前玩家“

i
”有两个领土,“马耳他”和“戈佐岛”。

fullTerritoriesInRange 数组:

[
  ['357', 'Malta'],
  [
    ['Gozo', <internalArray>, 0.2],
    ['Tunisia', <internalArray>, 0.3],
    ['Italy', <internalArray>, 0.34],
  ]
],
[
  ['358', 'Gozo'],
  [
    ['Malta', <internalArray>, 0.42],
    ['Tunisia', <internalArray>, 0.3],
    ['Italy', <internalArray>, 0.34],
  ]
]

attackableTerritoriesInRange 数组应如下所示,删除了拥有的区域:

[
  ['357', 'Malta'],
  [
    ['Tunisia', <internalArray>, 0.3],
    ['Italy', <internalArray>, 0.34],
  ]
],
[
  ['358', 'Gozo'],
  [
    ['Tunisia', <internalArray>, 0.3],
    ['Italy', <internalArray>, 0.34],
  ]
]

我真的试图解释这一点,我知道这看起来很复杂,但我需要了解信息,而且它非常复杂,但解决方案可能比阅读问题更容易。请尝试通过提及我的方法是否错误或通过更正代码来帮助我,因为目前它返回一个空数组,fullTerritoriesInRange[j][1] 的长度大于 1,并且如果它是 1 ,它首先返回 fullTerritoriesInRange 数组中的所有领土,并且多次返回。有什么遗漏的地方请随时问我。如果需要的话,我可以提供创建任何其他数组的所有 javascript,并且如果需要的话,我会很乐意提供整个函数,以查看更多上下文。

此问题涉及一个全球可用的应用程序,可以在以下位置查看: https://leighhobson89.itch.io/dominationwc

当前版本有console.log,因此您可以根据需要查看问题。要重现,请在链接处加载游戏(由于间歇性异步错误,可能需要一次 f5),然后单击任何区域并单击“确认”。当它完成初始化时,单击绿色的“军事”按钮两次,然后查看控制台输出,您可以在那里看到这个问题中的所有内容。感谢您的阅读。

javascript arrays multidimensional-array
2个回答
0
投票

我建议找到一种更好的方法来跟踪您的数据,根据网站,这似乎将成为一个非常大且复杂的项目,找到一种更好的方法来跟踪数据,虽然现在很难,但会受益从长远来看,你。

但是如果我理解正确的话,这段代码应该可以解决你的问题,很难理解你的问题和数据,所以这可能无法按你想要的方式工作。如果您可以提供更完整、格式更好的数据集,我可以改进这个解决方案。

简而言之,我所做的不是推送整个子数组(即 fullTerritoriesInRange[j][1]),而是推送一个包含领土名称及其内部数组的新子数组。另外,你应该只推送不属于玩家的领土,所以我调整了 if (!isOwned) 条件的位置。

const attackableTerritoriesInRange = [];
for (let j = 0; j < fullTerritoriesInRange.length; j++) {
    let isOwned = false;

    for (let k = 0; k < fullTerritoriesInRange[j][1].length; k++) {
        const territoryNameToCheck = fullTerritoriesInRange[j][1][k][0];
        for (let l = 0; l < arrayOfLeadersAndCountries[i][2].length; l++) {
            const ownedTerritoryName = arrayOfLeadersAndCountries[i][2][l].territoryName;
            if (territoryNameToCheck === ownedTerritoryName) {
                isOwned = true;
                break;
            }
        }
        if (isOwned) {
            break;
        }
    }

    if (!isOwned) {
        const territoryData = [fullTerritoriesInRange[j][0], fullTerritoriesInRange[j][1]];
        attackableTerritoriesInRange.push(territoryData);
    }
}

console.log("and the attackable territories are:");
console.log(attackableTerritoriesInRange);


0
投票

我已将此答案标记为解决方案,它并没有完全按照原来的方式工作,但它绝对让我走上了正确的轨道,只需要更改一两行,并且基于仅拥有我可以的信息提供我的问题,这非常有帮助。我还从这个问题中得到了一些关于组织数据的好主意。

最后,我决定更改此数组的范围,在创建没有所属区域的数组后,我会将其简化为

territoryName
字符串的一维列表,稍后我可以唯一地识别它以获得来自主数据对象数组和
fullTerritoriesInRange
数组的实际数据。重要的是把已经完成的领地撤走。感谢大家!

let attackableTerritoriesInRange = [];
        for (let j = 0; j < fullTerritoriesInRange.length; j++) {
            let isOwned = false;

            for (let k = 0; k < fullTerritoriesInRange[j][1].length; k++) {
                const territoryNameToCheck = fullTerritoriesInRange[j][1][k][0];
                for (let l = 0; l < arrayOfLeadersAndCountries[i][2].length; l++) {
                    const ownedTerritoryName = arrayOfLeadersAndCountries[i][2][l].territoryName;
                    if (territoryNameToCheck === ownedTerritoryName) {
                        isOwned = true;
                        break;
                    }
                }
                if (!isOwned) {
                    attackableTerritoriesInRange.push(fullTerritoriesInRange[j][1][k]);
                }
                isOwned = false;
            }
        }

        attackableTerritoriesInRange = formatAttackableTerritoriesArray(attackableTerritoriesInRange);
        console.log("and the attackable territories are:");
        console.log(attackableTerritoriesInRange);
© www.soinside.com 2019 - 2024. All rights reserved.