2015-04-02 230 views
2

也許我構造這個代碼是錯誤的(第一次使用Javascript),但我想採取用戶輸入並搜索數組數組來檢查具有該名稱的數組存在。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); 
 
};

請讓我知道這是錯誤的結構性原因,這是我在第一眼結構的想法。

謝謝!

回答

1

正如上文所述,這將是最好的,使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"); 

那麼你的飲食構造也變得簡單,只需要名稱和位置屬性:

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。然後,您可以使用位置對象上的原生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屬性將變得不那麼重要(或可能無用)。

+0

非常感謝你的幫助。肯定會學到很多我不知道的東西。只是幾個簡單的問題:在這種情況下e.preventDefualt()的目的是什麼,querySelector()比getElementById()有什麼優勢? – Mark 2015-04-02 20:05:53

+0

_e_是我給我的事件處理函數的第一個參數的名稱 - 在JS中,這總是事件本身。該事件具有各種屬性(鼠標位置,事件類型,目標等) - 你可以在這裏閱讀:https://developer.mozilla.org/en/docs/Web/API/Event。因爲我使用了表單在我的示例中,「點擊」提交事件的默認操作是將表單提交到表單中指定的URL。 – Sidd 2015-04-02 20:46:58

+0

...但我不想提交給另一個URL,我只使用了表單,以便我可以使用輸入值(最重要的是,填充字段後按「enter」也會觸發處理程序像點擊) - 所以我必須使用_e.preventDefault()_來防止此默認操作。每當有一個與事件相關的默認動作(比如去一個不同的頁面或其他東西),並且你想覆蓋它時,_event.preventDefault()_就是你的朋友。否則,處理程序中的代碼將運行,然後繼續執行默認操作。 – Sidd 2015-04-02 20:48:12

0

您正在使用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();

+0

謝謝,但是是的insertFood(x)在那裏之前,我似乎不得不錯誤地放在代碼複製時,它也創建insertFood在createFood函數之外,然後遷移它,所以現在我應該改變參數名稱。 – Mark 2015-04-02 19:32:48

+0

是的,我只是看到雖然我改變了位置來反對代碼沒有完全更新,它應該是現在。 – SGD 2015-04-02 19:37:01