使用数组元素填充提示并将其编号

时间:2015-08-17 13:41:02

标签: javascript arrays alert

(Stack Overflow没有标记提示'因此我使用了警报,因为我猜它类似于吸引正确的回答者。)

您好, 我目前正在为大学的作业制作一个基于JavaScript的游戏。我通常很擅长解决问题,但是被这个问题困扰了。

为了解释,我有一个数组,列出玩家可以选择的可能的装甲槽。可以选择这些,并且每次选择被推送到第二个数组,该数组处理已经被拾取的内容(以及以什么顺序)并且该项目从原始数组进行拼接。有一个while循环贯穿,直到所有3个被挑选。

var armourSlotToPick = ["Head", "Chest", "Legs"],    
    armourSlotPicked = [],
    armourLoop = 1,
    indexArmour = 0;

function numInArray() {
    indexArmour++;
    return (indexArmour + ". " + armourSlotToPick[indexArmour - 1] + "\n");
}


function armour() {
    while (armourLoop < 4) {
        var armourPick = prompt("Pick an armour slot to generate an item for:\n" + armourSlotToPick.forEach(numInArray));
        if (armourPick == 1) {
            armourSlotPicked.push(armourSlotToPick[0]);
            armourSlotToPick.splice(0,1);
        } else if (armourPick == 2) {
            armourSlotPicked.push(armourSlotToPick[1]);
            armourSlotToPick.splice(1,1);
        } else if (armourPick == 3) {
            armourSlotPicked.push(armourSlotToPick[2]);
            armourSlotToPick.splice(2,1);
        } else {
            alert("Invalid choice, you suck");
            break;
        }
        armourLoop++;
    }
}

我知道可能无法在numInArray()中对提示进行整个返回,但它显示有些工作。

现在的问题是:我让它工作,以便数组中的每个项目都被编号(var armourSlotToPick = [&#34; 1.Head&#34;,&#34; 2.Thst&#34;,&#34 ; 3. Legs&#34;],但正如你所看到的,如果玩家选择2,那么下次它将显示&#34; 1。头(新线)3。腿&#34;当玩家选择3时,会出现问题,因为他们真的要选择2.如何在一个提示中对数组中的项进行编号?

我可能在想这个,但我现在已经受了几个小时了。

我提前感谢您提供的任何见解,

丹尼尔。


编辑:已解决。

以下是最终结果,与Jonathan Brooks的编辑答案略有不同。

var armourSlotToPick = [null, "Head", "Chest", "Legs"]
var armourSlotPicked = [null];
var armourLoop = 1;

function armour() {
    while (armourLoop < 4) {
        var message = "Pick an armour slot to generate an item for:\n";
        for (var i = 0; i < armourSlotToPick.length; i++) {
            if (armourSlotToPick[i] !== null) {
                message += "" + i + ". " + armourSlotToPick[i] + "\n"; 
            }            
        }
        var armourPick = prompt(message);
        if (armourPick > armourSlotToPick.length-1 || armourPick < 1) {
            alert("Invalid choice, you suck");
        } else {
            var insert = armourSlotToPick.splice(armourPick, 1);
            armourSlotPicked.push(insert);
        }
        armourLoop++;
    }
    armourSlotPicked.splice(0,1);
}

armour();
alert(armourSlotPicked.join("\n"));

我感谢所有为这次讨论和最终结果做出贡献的人,我希望这是人们可能与此类似的未来问题的一个很好的例子。

3 个答案:

答案 0 :(得分:1)

使用结构/对象作为数组中的内容,而不仅仅是值。

基本概念:

armourSlotPicked.push({ "key": 1, "value":armourSlotToPick[1]})
alert("value: " + armourSlotPicked[0].value)
alert("key: " + armourSlotPicked[0].key)

编辑:回复评论可能需要一些空间。

恕我直言,提示是一个完全错误的工具,因为大多数浏览器会要求用户许可防止多个弹出窗口,并且因为promt只能返回1条信息,所以每个弹出窗口只能要求1个东西。相反,你应该使用div元素,每个信息都有复选框..

据说它很容易用在一个promt中。 提示只是一个内置函数,它将一个字符串作为参数(在弹出窗口中显示为文本)并返回一个包含用户输入的字符串。

对你来说,神奇的是: array.foreach():forEach()方法为每个数组元素执行一次提供的函数。

在你的情况下,这意味着它调用一个函数,为数组中的每个元素返回一个字符串,并连接字符串。

在过去你会写下这个:

var messageText= "Pick an armour slot to generate an item for:\n"
for(var i = 1; i < armourSlotToPick.length; i++){
    messageText += i + ". " + armourSlotToPick[i- 1] + "\n";
}
var armourPick = prompt(messageText);

但是在这个现代时代,您定义了一个打印功能,并使用它来生成循环:

function numInArray() {
    indexArmour++;
    return (indexArmour + ". " + armourSlotToPick[indexArmour - 1] + "\n");
}

//more code before we get to where the function is used....

indexArmour = 0;
var messageText = "Pick an armour slot to generate an item for:\n" + armourSlotToPick.forEach(numInArray);
var armourPick = prompt(messageText);

或在代码中的一行中:     indexArmour = 0; //你忘了这个 - 否则列表只会完成一次?     var armourPick = prompt(&#34;选择一个装甲槽来生成一个项目:\ n&#34; + armourSlotToPick.forEach(numInArray));

它产生相同的输出,因为它做同样的事情,它只是写得非常不同!

如果数组包含&#34;对象文字&#34;而不是简单的值,正如我所说,旧式代码看起来像这样:

function contains(a, value) {
    try{
        for (var i = 0; i < a.length; i++) {
            if (a[i].value == value) {
                return true;
            }
        }
    }
    catch(err) {
       // do nothing 
    };
    return false;
}

以后......

for(var j = 0; j < 4; j++){
    for(var i = 0; i < Math.min(armourSlotToPick.length); i++){
        if( contains(armourSlotPicked, armourSlotToPick[i- 1]) )

继续;             var messageText =&#34;为插槽中的装甲生成一个项目:&#34; + i +&#34; \ n&#34;                 messageText + = armourSlotToPick [i-1] +&#34; \ n&#34 ;;         }

    var armourPick = prompt(messageText);
    if (armourPick > 0 && armourPick < armourSlotToPick.length) {
        armourSlotPicked.push({"key":j, "value":armourSlotToPick[armourPick]);
    }
    ...
}
//now we have an array that holds information about when what was picked..

或类似的东西..这是完全未经测试的bt.w,它只是为了说明

答案 1 :(得分:1)

查看我的fiddle,我认为我有一个有效的解决方案。

你真正想要使用的是带有自己索引的对象文字(从1开始) - 如果是我,我会创建自己的方法来迭代这个自定义索引,方法是在Object的原型中添加一个方法,但是我离题了。

使用while循环使代码过于复杂,而且大量的if语句是不必要的:相反,您只需要对输入进行一些基本验证然后就可以了信任任何输入通过此验证。这在这里得到证明:

if ( armourPick > armourSlotToPick.length || armourPick < 1 ) {
    alert("Invalid choice, you suck");
}
else {
    armourSlotPicked.push( armourSlotToPick[armourPick-1] )
    alert (armourSlotPicked[armourSlotPicked.length-1].value);
}

仔细阅读我的代码,您应该更好地了解如何处理某些问题。

修改

根据您的要求,我认为我有一个适合您需求的解决方案。基本上,要使数组在索引1处“开始”所要做的就是用null值填充第0个元素,如下所示:

var armourSlotToPick = [null, "Head", "Chest", "Legs"]
var armourSlotPicked = [null];

您只需记住在代码中考虑此null对象,例如:

if (armourSlotToPick[i] !== null) {
    message += "" + i + "\n"; 
}  

指数会自动更新。有关详细信息,请参阅此updated fiddle

答案 2 :(得分:0)

您希望使用数组索引为项目编号。由于您的数字是从一开始的,索引是从零开始的,因此在输出和解释响应时,您需要在两者之间进行转换。

这种方法还允许你在if-else语句中消除除了两个案例之外的所有案例。