用数组的元素填充提示符,并给它们编号

Populate a prompt with elements of an array and number them off

本文关键字:编号 提示符 数组 元素 填充      更新时间:2023-09-26

(Stack Overflow没有'prompt'标签,所以我使用alert,因为我猜它足够相似,可以吸引正确的答案。)

你好,我目前正在为大学的作业制作一款基于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 =["1。头"、"2。胸"、"3。但是正如你所看到的,如果玩家选择了2,那么下一次它就会显示"1"。标题(新行)当玩家选择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"));

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

看看我的小提琴,我想我有一个有效的解决方案。

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

使用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"; 
}  

索引将自动更新。请参阅此更新小提琴了解更多细节。

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

基本概念:

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

编辑:回复评论会占用一些空间

恕我直言,提示符是一个完全错误的工具,因为大多数浏览器会要求用户允许来防止多个弹出窗口,因为一个提示符只能返回一条信息,你只能在每个弹出窗口请求一件事。相反,您应该使用div元素,每个信息都带有复选框。

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

对你的魔力实际上是这样的: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("选择一个装甲槽来生成一个物品:'n" + armourslottpick . foreach (numInArray));

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

如果数组包含"对象字面量"而不是简单的值,如我所建议的,老式代码将看起来像这样:

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 = "生成一个物品的装甲槽:" + i + "'n"messageText += armourSlotToPick[i- 1] + "'n";}

    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..

之类的…这是完全未经测试的,只是为了说明

您希望使用数组索引对项目进行编号。由于您的数字是以1为基础的,而索引是以0为基础的,因此在输出和解释响应时需要在两者之间进行转换。

这种方法还允许您在if-else语句中消除除两种情况外的所有情况。