#javascript #arrays #function #comparison #operators
#javascript #массивы #функция #сравнение #операторы
Вопрос:
Функция expensiveItem(menu) должна возвращать самый дорогой элемент в массиве, питание. В этом случае он должен возвращать «Двойную четверть фунта с сыром». Вместо этого он возвращает «Двойной чизбургер». Где я ошибся в своем коде?
var item1 = {
name: "Big Mac",
price: 3.99,
calories: 530
};
var item2 = {
name: "Filet-O-Fish",
price: 3.79,
calories: 390
};
var item3 = {
name: "Double Cheeseburger",
price: 1.59,
calories: 430
};
var item4 = {
name: "Double Quarter Pounder with Cheese",
price: 4.79,
calories: 740
};
var item5 = {
name: "Chicken McNuggets",
price: 4.49,
calories: 190
};
var meals = [item1, item2, item3, item4, item5];
function init() {
var lowestCost = document.getElementById('cheapestItem');
lowestCost.onclick = function() {
cheapestItem(meals);
}
var highestCost = document.getElementById('highestCost');
highestCost.onclick = function() {
expensiveItem(meals);
}
}
window.onload = init;
// return name of cheapest item on menu
function cheapestItem(menu) {
var msg = document.getElementById('msg1'); // is this necessary? Code works fine without it...
var cheapestItem = operation(menu, "less");
msg1.innerHTML = "The cheapest item is " cheapestItem;
}
// return name of most expensive item on menu
function expensiveItem(menu) {
var msg = document.getElementById('msg2');
var expensiveItem = operation(menu, "greater");
msg2.innerHTML = "The most expensive item is " expensiveItem;
}
//return result based on given comparator operator
function operation(menu, op) {
var v1 = menu[0].price;
var item;
for (var i = 0; i < menu.length; i ) {
var v2 = menu[i].price;
if ((op == "less" amp;amp; (v2 < v1)) ||
(op == "greater" amp;amp; (v2 > v1))) {
result = v2;
item = menu[i].name;
}
}
console.log(item);
return item;
}
<body>
<input type="button" id="cheapestItem" value="Cheapest Item">
</div>
<p id="msg1">message 1</p>
<input type="button" id="highestCost" value="Most Expensive Item">
</div>
<p id="msg2">message 2</p>
</body>
Комментарии:
1. Просто побочный узел, вам нужно присвоить значение item
var item = menu[0].name;
, потому что он завершится неудачей, если первый элемент будет самым большим или самым маленьким, в зависимости отop
.
Ответ №1:
Проблема здесь:
if ((op == "less" amp;amp; (v2 < v1)) || (op == "greater" amp;amp; (v2 > v1)))
Вы только сравниваете v1
и v2
, но вы также должны присвоить v1
значение v2
, если условие выполнено.
Объяснение:
Ниже приведены значения в цикле
3.99 3.99
3.99 3.79
3.99 1.59
3.99 4.79
4.79 4.49
Если вы заметили, последние 2 операции удовлетворяют условию. Таким образом, вы получите последнее.
var item1 = {
name: "Big Mac",
price: 3.99,
calories: 530
};
var item2 = {
name: "Filet-O-Fish",
price: 3.79,
calories: 390
};
var item3 = {
name: "Double Cheeseburger",
price: 1.59,
calories: 430
};
var item4 = {
name: "Double Quarter Pounder with Cheese",
price: 4.79,
calories: 740
};
var item5 = {
name: "Chicken McNuggets",
price: 4.49,
calories: 190
};
var meals = [item1, item2, item3, item4, item5];
function init() {
var lowestCost = document.getElementById('cheapestItem');
lowestCost.onclick = function() {
cheapestItem(meals);
}
var highestCost = document.getElementById('highestCost');
highestCost.onclick = function() {
expensiveItem(meals);
}
}
window.onload = init;
// return name of cheapest item on menu
function cheapestItem(menu) {
var msg = document.getElementById('msg1'); // is this necessary? Code works fine without it...
var cheapestItem = operation(menu, "less");
msg1.innerHTML = "The cheapest item is " cheapestItem;
}
// return name of most expensive item on menu
function expensiveItem(menu) {
var msg = document.getElementById('msg2');
var expensiveItem = operation(menu, "greater");
msg2.innerHTML = "The most expensive item is " expensiveItem;
}
//return result based on given comparator operator
function operation(menu, op) {
var v1 = menu[0].price;
var item;
for (var i = 0; i < menu.length; i ) {
var v2 = menu[i].price;
if ((op == "less" amp;amp; (v2 <= v1)) ||
(op == "greater" amp;amp; (v2 >= v1))) {
result = v1 = v2;
item = menu[i].name;
}
}
console.log(item);
return item;
}
<body>
<input type="button" id="cheapestItem" value="Cheapest Item">
</div>
<p id="msg1">message 1</p>
<input type="button" id="highestCost" value="Most Expensive Item">
</div>
<p id="msg2">message 2</p>
</body>
Альтернативный способ
Отсортируйте свой массив init
. Теперь вам не нужно выполнять цикл, чтобы получить минимальные и максимальные значения.
Примечание: его плохая практика использования window.load = function
, вы должны использовать window.addEventListener('load', function)
вместо
var item1 = {
name: "Big Mac",
price: 3.99,
calories: 530
};
var item2 = {
name: "Filet-O-Fish",
price: 3.79,
calories: 390
};
var item3 = {
name: "Double Cheeseburger",
price: 1.59,
calories: 430
};
var item4 = {
name: "Double Quarter Pounder with Cheese",
price: 4.79,
calories: 740
};
var item5 = {
name: "Chicken McNuggets",
price: 4.49,
calories: 190
};
var meals = [item1, item2, item3, item4, item5];
var OP_LESS = "less";
var OP_GREATER = "greater";
function init() {
var lowestCost = document.getElementById('cheapestItem');
lowestCost.onclick = function() {
cheapestItem(meals);
}
var highestCost = document.getElementById('highestCost');
highestCost.onclick = function() {
expensiveItem(meals);
}
sortData();
}
function sortData(){
meals.sort(function(a,b){
return a.price > b.price ? 1 : a.price < b.price ? -1 : 0
});
}
window.addEventListener('load', init);
// return name of cheapest item on menu
function cheapestItem(menu) {
var msg = document.getElementById('msg1'); // is this necessary? Code works fine without it...
var cheapestItem = operation(menu, OP_LESS);
msg1.innerHTML = "The cheapest item is " cheapestItem;
}
// return name of most expensive item on menu
function expensiveItem(menu) {
var msg = document.getElementById('msg2');
var expensiveItem = operation(menu, OP_GREATER);
msg2.innerHTML = "The most expensive item is " expensiveItem;
}
//return result based on given comparator operator
function operation(menu, op) {
return (op === OP_LESS ? meals[0] : meals[meals.length-1]).name
}
<body>
<input type="button" id="cheapestItem" value="Cheapest Item">
</div>
<p id="msg1">message 1</p>
<input type="button" id="highestCost" value="Most Expensive Item">
</div>
<p id="msg2">message 2</p>
</body>
Комментарии:
1. ооо, я изменил имена переменных, но никогда не менял «результат» на «v1». Спасибо, хороший улов! 🙂
Ответ №2:
Вы всегда сравниваете с начальным значением v1, когда вы находите «большее», вы должны установить новое значение var v1.
if ((op == "less" amp;amp; (v2 < v1)) ||
(op == "greater" amp;amp; (v2 > v1))) {
result = v2;
v1=v2; //Set new greater/lower value
item = menu[i].name;
}
Комментарии:
1. Да, теперь я вижу, я изменил имена переменных, но никогда не менял «результат» на «v1». Спасибо! 🙂
Ответ №3:
Я предлагаю использовать только одну переменную для проверки и возврата
function operation(menu, op) {
var price = menu[0].price,
item = menu[0].name;
for (var i = 0; i < menu.length; i ) {
if (
op === "less" amp;amp; menu[i].price < price ||
op === "greater" amp;amp; menu[i].price > price
) {
price = menu[i].price;
item = menu[i].name;
}
}
console.log(item);
return item;
}
var item1 = { name: "Big Mac", price: 3.99, calories: 530 };
var item2 = { name: "Filet-O-Fish", price: 3.79, calories: 390 };
var item3 = { name: "Double Cheeseburger", price: 1.59, calories: 430 };
var item4 = { name: "Double Quarter Pounder with Cheese", price: 4.79, calories: 740
};
var item5 = { name: "Chicken McNuggets", price: 4.49, calories: 190 };
var meals = [item1, item2, item3, item4, item5];
function init() {
var lowestCost = document.getElementById('cheapestItem');
lowestCost.onclick = function() {
cheapestItem(meals);
}
var highestCost = document.getElementById('highestCost');
highestCost.onclick = function() {
expensiveItem(meals);
}
}
window.onload = init;
// return name of cheapest item on menu
function cheapestItem(menu) {
var msg = document.getElementById('msg1'); // is this necessary? Code works fine without it...
var cheapestItem = operation(menu, "less");
msg1.innerHTML = "The cheapest item is " cheapestItem;
}
// return name of most expensive item on menu
function expensiveItem(menu) {
var msg = document.getElementById('msg2');
var expensiveItem = operation(menu, "greater");
msg2.innerHTML = "The most expensive item is " expensiveItem;
}
//return result based on given comparator operator
function operation(menu, op) {
var price = menu[0].price,
item = menu[0].name;
for (var i = 0; i < menu.length; i ) {
if (op == "less" amp;amp; menu[i].price < price || op == "greater" amp;amp; menu[i].price > price) {
price = menu[i].price;
item = menu[i].name;
}
}
console.log(item);
return item;
}
<input type="button" id="cheapestItem" value="Cheapest Item">
<p id="msg1">message 1</p>
<input type="button" id="highestCost" value="Most Expensive Item">
<p id="msg2">message 2</p>
Комментарии:
1. Привет, Нина, есть ли причина, по которой вы это предлагаете? Я думал, что присвоение переменной ‘menu [i].price’ сделает код более чистым и сделает его менее избыточным. Но, может быть, это не имеет большого значения?
2. еще один шаг, я бы взял только индекс меню, который является минимальным или максимальным. только для возврата значения я бы вернул имя
menu[index]
. причина использования только одного параметра vsariable заключается в том, чтобы всегда сохранять его равным приличному значению. если вы используете две переменные, вы можете перепутать контекст переменных.