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

Javascript: Using user input to search an array of arrays

本文关键字:输入 搜索 数组 用户 Javascript      更新时间:2023-09-26

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

我第一次尝试使用eval()函数,有人告诉我这个函数不好,但当有匹配时它会起作用,但当不存在匹配时它就会失败。

该程序的基本前提是有一个包含位置的数组,这些位置随后是包含食物项目的数组。用户输入食物的名称和他们想放在哪里,它将创建一个食物对象,将该对象插入数组中的正确位置,并将该项目输入到以html显示的列表中。

以下是迄今为止的所有代码:

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);
};

请让我知道这是不是结构错误,因为这是我的第一眼结构的想法。

谢谢!

如上所述,最好将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构造函数也变得更简单,只需要名称和位置属性:

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

然后,您也可以直接通过名称调用任何特定位置(如果您要像在代码中那样全局声明它),或者更恰当地(如果您像在SGD的代码中那样声明对象内部的数组)通过locations[location]调用,其中location只是一个包含"冷冻室"、"餐具室"或"冰箱"的字符串。您也可以通过locations[someFood.location]调用数组。

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

编辑后添加:如果目标是以后要在保存食物的所有位置按食物的名称查找食物,最好在locations[location]中添加/推送foodObj.name,而不是整个foodObj。然后,您可以在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属性就会变得不那么重要(或者可能毫无用处)。

您使用Food作为函数/构造函数和参数名称(但这不应该是问题,但以后可能会引起麻烦),并且您从未调用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();