Есть массив с объектами (deliveryCost - страна и стоимость доставки в страну). Необходимо реализовать вызов функции с запрашиваемой страной: если она (country) есть в массиве - отобразить стоимость доставки (cost). Если её нет, просто отобразить в консоли: "В вашу страну доставка не осуществляется".
Я пробовал через перебор массива (map, filter, find..) - в моей реализации, когда страна не найдена, все равно перебирается весь массив и выводится сообщение столько раз, сколько объектов в массиве. Значит, неверна сама реализация.
Подскажите, где я допускаю ошибку. Спасибо Вам!
const deliveryCost = [
{ country: "Китай", cost: 100 },
{ country: "Чили", cost: 250 },
{ country: "Австралия", cost: 170 },
{ country: "Индия", cost: 80 },
{ country: "Ямайка", cost: 120 }
];
const countryForDelivery = (arr, countryName) => {
arr.map(elem => {
if (elem.country === countryName) {
yesDelivery(elem.country, elem.cost);
} else {
noDelivery(countryName);
}
});
};
function yesDelivery(country, cost) {
console.log(`Доставка в ${country} будет стоить ${cost} кредитов`);
}
function noDelivery(country) {
console.log(`В ${country} доставка не доступна`);
}
countryForDelivery(deliveryCost, "Индия"); // есть в списке
countryForDelivery(deliveryCost, "Исландия"); // нет в списке
Вам map
в данном случае не нужен, т.к. он предназначен для создания нового массива на основании существующего (т.е. для каждого элемента вызывается ваша функция, поэтому в консоли и куча сообщений). Вам достаточно с помощью filter
/find
найти нужный элемент и если он есть выводить одно сообщение, если нет - другое.
const countryForDelivery = (arr, countryName) => {
const elem = arr.find(elem => elem.country === countryName);
if (elem) {
yesDelivery(elem.country, elem.cost);
} else {
noDelivery(countryName);
}
};
Обычно, имеет смысл создать производный Map
(или обычный объект) для скоростного доступа по одному из полей, без какого-либо перебора вложенных объектов.
Почему это лучше - потому что объекты это хэш-таблицы. При доступе по ключам, интерпретатор использует только их хэши (а это значительно быстрее, чем любой перебор в юзеркоде, будь то for
+if
или find
).
Объект Map, и внешняя функция (внутренний поиск чуть быстрее):
const deliveryCostData = [
{ country: "Китай", cost: 100 },
{ country: "Чили", cost: 250 },
{ country: "Австралия", cost: 170 },
{ country: "Индия", cost: 80 },
{ country: "Ямайка", cost: 120 }
];
const deliveryCostMap = deliveryCostData.reduce(
(rslt, obj) => rslt.set(obj.country, obj)
, new Map);
const deliveryFor = country => {
const entry = deliveryCostMap.get(country);
if (!entry || (typeof entry.cost === 'undefined'))
console.log(`В ${country} доставка не доступна`);
else
console.log(`Доставка в ${country} будет стоить ${entry.cost} кредитов`);
};
deliveryFor('Индия'); // есть в списке
deliveryFor('Исландия'); // нет в списке
Обычный объект, с методом (удобнее благодаря инкапсуляции):
const deliveryCostData = [
{ country: "Китай", cost: 100 },
{ country: "Чили", cost: 250 },
{ country: "Австралия", cost: 170 },
{ country: "Индия", cost: 80 },
{ country: "Ямайка", cost: 120 }
];
const delivery = deliveryCostData.reduce(
(rslt, obj) => Object.assign(rslt, { [obj.country]: obj })
, {
forCountry(country) {
if (this.hasOwnProperty(country))
console.log(`Доставка в ${country} будет стоить ${this[country].cost} кредитов`);
else
console.log(`В ${country} доставка не доступна`);
},
}
);
delivery.forCountry('Индия'); // есть в списке
delivery.forCountry('Исландия'); // нет в списке
В обоих случаях имеет смысл присваивать в качестве значения весь объект, а не только его поле cost
. Потому что:
Эффективно по ресурсам (1. объекты присваиваются по ссылке, доп. память не выделяется; 2. интерпретатору не нужно запоминать дублирующую схему объектов, и выполнять сопутствующие проверки схем на каждой итерации построения словаря)
Как следствие передачи по ссылке, получаем взаимосвязь данных в объектах и возможность упрощения логики (изменение cost
или добавление новых свойств в объекты deliveryCostData
, автоматически отразится на объектах в словаре - при таких операциях, нет нужды его перестраивать)
Значительно упрощается поддержка кода (если в будущем добавятся еще "постоянные" поля помимо cost
, код не нужно будет переписывать - достаточно будет дополнить его новыми хелперами/методами).
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Всем приветВ проекте стоит задача, в котором стартовый URL должен начинаться с абривеатуры языка
подскажите как решить проблему с тестами мой основной js (activeBtnClickjs):