【问题标题】:Can I use a loop to optimize my code?我可以使用循环来优化我的代码吗?
【发布时间】:2015-01-14 20:14:27
【问题描述】:

我正在尝试优化我的代码,使其更高效、更易于阅读。我有一些组合的 if 语句,我认为这可能会更好,如果将它们转换为 for 循环,我只是不确定该怎么做?

这是我的代码:

    if (starportSelected){
        if(game.currentLevel.requirements.vehicles.indexOf('transport')>-1 && cashBalance>=vehicles.list["transport"].cost){
            $("#transportbutton").removeAttr("disabled");
        }
        if(game.currentLevel.requirements.vehicles.indexOf('scout-tank')>-1 && cashBalance>=vehicles.list["scout-tank"].cost){
            $("#scouttankbutton").removeAttr("disabled");
        }
        if(game.currentLevel.requirements.vehicles.indexOf('heavy-tank')>-1 &&cashBalance>=vehicles.list["heavy-tank"].cost){
            $("#heavytankbutton").removeAttr("disabled");
        }
        if(game.currentLevel.requirements.vehicles.indexOf('harvester')>-1 && cashBalance>=vehicles.list["harvester"].cost){
            $("#harvesterbutton").removeAttr("disabled");
        }
        if(game.currentLevel.requirements.aircraft.indexOf('chopper')>-1 && cashBalance>=aircraft.list["chopper"].cost){
            $("#chopperbutton").removeAttr("disabled");
        }
        if(game.currentLevel.requirements.aircraft.indexOf('wraith')>-1 && cashBalance>=aircraft.list["wraith"].cost){
            $("#wraithbutton").removeAttr("disabled");
        }   
    }

我认为第一步是创建两个数组,一个用于车辆,一个用于飞机,如下所示:

    var vehicles = ['transport', 'scout.tank', 'heavy-tank', 'harvester'];
    var aircraft = ['chopper', 'wraith'];

但是如何获取其余代码并将其更改为 for-loop 对我来说似乎是一个难题。 所有帮助和解释将不胜感激!

【问题讨论】:

  • 如果你有两个数组,你将不得不遍历它们。看起来你的代码需要一个用于车辆的嵌套 for 循环,以及用于飞机的嵌套循环。这是 O(n^2) 这不是很好。索引哈希表中的特定位置(我假设您有哈希表每次查找将花费 O(1),如果您有 n 个元素并遍历所有元素,总共可以花费 O(n)解释你的代码试图做什么?
  • 这里为什么需要 2 个特定的数组?为什么不合并成一个对象?
  • 如果您关心性能,您应该为重复的对象访问设置别名。 var foo = game.currentLevel.requirements.vehicles; 然后foo.indexOf('blah')
  • 在游戏中我有一个名为 startport 的对象。当玩家选择星港时,只要玩家有足够的资金,就可以在侧边栏菜单中选择车辆或飞机。代码现在可以正常工作,但我相信使用某种循环可能会更好,我只是不确定如何编写它?
  • @Sushanth-- game.currentLevel.requirements.aircraft.indexOfgame.currentLevel.requirements.vehicles.indexOf 是不同的行。

标签: javascript jquery arrays if-statement for-loop


【解决方案1】:

您似乎有 "vehicles""aircraft" 类型,每个类型都有多个值。

因此,我会为值数组创建一个类型对象。

因为您还使用了名为 vehiclesaircraft 的变量,所以您需要在单独的对象中引用它们,以便您可以使用字符串查找它们。

var lists = {
    vehicles: vehicles,
    aircraft: aircraft
}

var obj = {
    vehicles: ["transport", "scout-tank", "heavy-tank", "harvester"],
    aircraft: ["chopper", "wraith"]
};

然后使用外循环和内循环。

//        v---("vehicles" or "aircraft")
for (var type in obj) { //      v---("transport", "scout-tank", "chopper", etc...)
    obj[type].forEach(function(val) {
        if(game.currentLevel.requirements[type].indexOf(val)>-1 && 
                     cashBalance >= lists[type].list[val].cost) {
            $("#" + val.replace("-", "") + "button").removeAttr("disabled");
        }
    });
}

还请注意,我必须替换 ID 选择器中的连字符,因为它没有用作 ID 的一部分。


如果您愿意,可以将顶部的两个对象合并为一个对象:

var obj = {
    vehicles: {
        list: vehicles,
        values: ["transport", "scout-tank", "heavy-tank", "harvester"]
    },
    aircraft: {
        list: aircraft,
        values: ["chopper", "wraith"]
    }
};

然后相应地调整循环引用。

如上所述,我还缓存了对象以提高性能。

for (var type in obj) {
    var list = obj[type].list;
    var requirements = game.currentLevel.requirements[type];

    obj[type].values.forEach(function(val) {
        if(requirements.indexOf(val)>-1 && cashBalance >= list[val].cost) {
            $("#" + val.replace("-", "") + "button").removeAttr("disabled");
        }
    });
}

为了使其比原来更高效,我们将删除一些 jQuery 调用。

for (var type in obj) {
    var list = obj[type].list;
    var requirements = game.currentLevel.requirements[type];

    for (var i = 0, vals = obj[type].values; i < vals.length; i++) {
        var val = vals[i];
        if(requirements.indexOf(val) > -1 && cashBalance >= list[val].cost) {
            document.getElementById(val.replace("-", "") + "button").disabled = false;
        }
    }
}

【讨论】:

  • @charles:这个问题已经有了展开的版本。他在问如何用循环缩短代码。并非所有代码都需要优化。有时清晰度和可扩展性更重要。
  • @charles:还要记住,这段代码依赖于已经非常昂贵的操作(DOM 选择/操作)。您发布的测试是非常轻量级的操作。所以在这种情况下,任何性能提升都不会被注意到。
  • 引用,“我正在尝试优化我的代码,使其更高效、更易于阅读。”他想要他的蛋糕,也想吃。您正在完成陈述的后半部分,但前半部分的方向错误。
  • 我更新了一个删除 jQuery 和 .forEach() 的版本。
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 2016-02-06
  • 2014-01-29
  • 1970-01-01
相关资源
最近更新 更多