Javascript: 使用用户输入搜索数组数组

Javascript: Using user input to search an array of arrays

也许我的代码结构有误(第一次使用 Javascript),但我想获取用户输入并搜索数组数组以检查是否存在具有该名称的数组。

我第一次尝试使用 eval() 函数,有人告诉我它不好,但它在有匹配项时有效,但在匹配项不存在时失败。

该程序的基本前提是有一个包含位置的数组,该数组随后是包含食物的数组。用户输入食物的名称和他们想要放置的位置,它会创建一个食物对象,将该对象插入数组中的正确位置,并将该项目输入到 [=30= 中显示的列表中].

这是目前所有的代码:

var fridge = [];
var freezer = [];
var pantry = [];

var locations = [fridge, freezer, pantry];


function Food(name, location, locationName){
    this.name = name;
    this.location = location;
    this.locationName = locationName;
    this.displayName = function(){
        alert(this.name);
    };
};
function createFood(){
    var name = prompt("Enter the items name:");
    var locationName = prompt("Enter a location to store it:")
    var location = eval(locationName);

    while(locations.indexOf(location) == -1){
        alert("This is not an actual location.");
        locationName = prompt("Please enter another location:");
        location = eval(locationName);
    };

    var x = new Food(name, location, locationName)

    function insertFood(Food){
        var a = locations.indexOf(Food.location);
        locations[a].push(Food);

        var list = document.getElementById(Food.locationName + "_items");
        var li = document.createElement("li");
        li.innerHTML = Food.name;
        list.insertBefore(li, list.lastChild);
    };

    insertFood(x);
};

如果结构有误请告诉我,因为乍一看这是我的结构想法。

谢谢!

您将 Food 用作 function/constructor 和参数名称(但这不应该是问题,但以后可能会引起麻烦)并且您从不调用 insertFood。此外,位置应该是对象而不是数组,这样您就可以像在代码中那样访问子数组。

var locations = {fridge : [], freezer:[], pantry:[]];


function Food(name, locationName){
    this.name = name;
    this.locationName = locationName;
    this.displayName = function(){
        alert(this.name);
    };
};
function createFood(){
    var name = prompt("Enter the items name:");
    var locationName = prompt("Enter a location to store it:")

    while(locationName in locations){
        alert("This is not an actual location.");
        locationName = prompt("Please enter another location:");
    };

    var x = new Food(name, locationName)

    function insertFood(food){
        locations[food.locationName].push(food);

        var list = document.getElementById(food.locationName + "_items");
        var li = document.createElement("li");
        li.innerHTML = food.name;
        list.insertBefore(li, list.lastChild);
    };
    // call the method now?
    insertFood(x);
};
createFood();

如上建议,最好使locations成为一个对象,这样你就可以有一个键(一个字符串)指向同名的数组。

    var fridge = [];
    var freezer = [];
    var pantry = [];

    var locations = {
        "fridge":fridge, 
        "freezer":freezer, 
        "pantry":pantry
    };

这样做的好处是您不需要 locationName,因为它从来没有真正发挥作用。您只需要使用本机 hasOwnProperty 函数检查 locations 对象是否具有与用户输入同名的 属性。类似于:

    if(!locations.hasOwnProperty(userInputLocation)) 
        alert("That is not a designated location");

那么你的 Food 构造函数也变得更简单,只需要 name 和 location 属性:

    function Food(name, location){
        this.name = name;
        this.location = location;
    }

然后您还可以直接通过名称调用任何特定位置(如果您要像在代码中那样全局声明它),或者更合适(如果您像在 SGD 中那样在对象内部声明数组代码)由 locations[location],其中 location 只是一个包含 "freezer" 或 "pantry" 或 "fridge" 的字符串。您也可以通过 locations[someFood.location].

调用数组

反正我不太喜欢提示和警报(更不用说评估了),所以我创建了一个使用输入字段的 jsBin,你可以在这里查看:http://jsbin.com/pamoquwuhu/1/edit

编辑添加: 如果你的目标是你以后想在食物保存的所有位置找到它的名字,最好是 add/push foodObj.name 而不是整个 foodObj in locations[location]。然后,您可以在 locations 对象上使用本机 for(property in object) 循环来查看可能存储所有给定食物的位置,并将其推入 results 数组。因此,您的 findFood 函数可能包含以下内容(假设 food 是要搜索的食物名称的用户输入字符串:

    var results = [];

    for(var loc in locations){ // loops through the property names in `locations`
        if(locations[loc].indexOf(food)>=0)
            results.push(loc);
    }

    if(!results.length){
        alert(food+' was not found');
    else
        alert(food+' was found in '+results.toString());

假设相同的食物可以存储在多个位置,并且您想通过名称查找给定的食物,那么您的食物对象的 location 属性 将变得不那么重要(或者可能无用) .