JavaScript grabbing certain values of multi-dimensional arrays - javascript

I'm trying to make a simple 'Choose Your Adventure!' game, and I seem to have run into a problem. I don't know how to target certain values of this multi-dimensional array I made.
I made a 'dealer/trader' and have his items on sale like this.
var dealer = [
[
{type: "weapon", cost: 250, name: "Claymore"},
{type: "weapon", cost: 75, name: "Dagger"},
{type: "weapon", cost: 350, name: "Magic Staff"},
{type: "weapon", cost: 150, name: "Sword"},
{type: "weapon", cost: 125, name: "Bow"},
{type: "weapon", cost: 125, name: "Crossbow"},
{type: "weapon", cost: 5, name: "Arrow"},
{type: "weapon", cost: 15, name: "Bolt"}
],
[
{type: "clothing", slot: "head", name: "Helmet"},
{type: "clothing", slot: "head", name: "Hood"},
{type: "clothing", slot: "chest", name: "Chestplate"},
{type: "clothing", slot: "chest", name: "Tunic"},
{type: "clothing", slot: "chest", name: "Robe"},
{type: "clothing", slot: "leggings", name: "Legplates"},
{type: "clothing", slot: "leggings", name: "Leggings"},
{type: "clothing", slot: "leggings", slot: "Undergarments"},
{type: "clothing", slot: "feet", name: "Boots"},
{type: "clothing", slot: "feet", name: "Armored Boots"}
]
]
And I have a function that operates the dealer, such as buying an item, I don't know how to target certain values/arrays. This is what I THINK will work.
function merchant() = {
var armor = function(slot, name, material) {
if(dealer[2].slot === "feet" && dealer[2].name = "Boots"}
money -= 10;
}
}
}
That should target the second array of the clothing and look for the slot feet and name of boots, right?

I would make the merchants array contain merchant objects. This allows you to give more information about a merchant, including items. I have two find methods. The first takes static arguments, the second allows for key-value parameters.
Note: I added a cost field to your boots, as this was somehow related to your example.
var merchants = [{
name : 'Weapons Merchant',
items : [
{type: "weapon", cost: 250, name: "Claymore"},
{type: "weapon", cost: 75, name: "Dagger"},
{type: "weapon", cost: 350, name: "Magic Staff"},
{type: "weapon", cost: 150, name: "Sword"},
{type: "weapon", cost: 125, name: "Bow"},
{type: "weapon", cost: 125, name: "Crossbow"},
{type: "weapon", cost: 5, name: "Arrow"},
{type: "weapon", cost: 15, name: "Bolt"}
]
}, {
name : 'Armor Merchant',
items : [
{type: "clothing", slot: "head", name: "Helmet"},
{type: "clothing", slot: "head", name: "Hood"},
{type: "clothing", slot: "chest", name: "Chestplate"},
{type: "clothing", slot: "chest", name: "Tunic"},
{type: "clothing", slot: "chest", name: "Robe"},
{type: "clothing", slot: "leggings", name: "Legplates"},
{type: "clothing", slot: "leggings", name: "Leggings"},
{type: "clothing", slot: "leggings", name: "Undergarments"},
{type: "clothing", slot: "feet", name: "Boots", cost : 10},
{type: "clothing", slot: "feet", name: "Armored Boots"}
]
}];
function main() {
// Static approach
var armorMerchant = findMerchant(merchants, 'Armor Merchant');
var boots = findItem(armorMerchant, 'clothing', 'Boots');
print('Boots: $' + boots.cost);
// Dynamic approach
var weaponsMerchant = findMerchant(merchants, 'Weapons Merchant');
var dagger = findWithParams(weaponsMerchant.items, {type:"weapon",name:"Dagger"});
print('Dagger: $' + dagger.cost);
}
function findMerchant(merchants, name) {
return find(merchants, function(merchant) {
return merchant.name === name;
});
}
function findItem(merchant, type, name) {
return find(merchant.items, function(item) {
return item.type === type && item.name === name;
});
}
function findWithParams(arr, parameters) {
return find(arr, function(item) {
for (var parameter in parameters) {
if (item[parameter] !== parameters[parameter]) {
return false;
}
return true;
}
});
}
function find(arr, predicateFn) {
var found = null;
arr.forEach(function(item, index, items) {
if (predicateFn.apply(undefined, arguments)) {
found = item;
return true;
}
return false;
});
return found;
}
function print(text) {
document.getElementById('out').innerHTML += text + '<br />';
}
main();
<div id="out"></div>

Related

Filter the desired items in the array and display them

I want to use the array methods to find the cheapest food in the menu and display the foods whose price is higher than 10 along with the name and ID in the console. Thank you for your help.
let menu = [
{ id: 1, name: "Soda", price: 3.12, size: "4oz", type: "Drink" },
{ id: 2, name: "Beer", price: 6.50, size: "8oz", type: "Drink" },
{ id: 3, name: "Margarita", price: 12.99, size: "12oz", type: "Drink" },
{ id: 4, name: "Pizza", price: 25.10, size: "60oz", type: "Food" },
{ id: 5, name: "Kebab", price: 31.48, size: "42oz", type: "Food" },
{ id: 6, name: "Berger", price: 23.83, size: "99oz", type: "Food" },
];
It's not very complex, just read the array with a FOR loop and filter the data with an IF .. :)
var menu = [
{ id: 1, name: "Soda", price: 3.12, size: "4oz", type: "Drink" },
{ id: 2, name: "Beer", price: 6.50, size: "8oz", type: "Drink" },
{ id: 3, name: "Margarita", price: 12.99, size: "12oz", type: "Drink" },
{ id: 4, name: "Pizza", price: 25.10, size: "60oz", type: "Food" },
{ id: 5, name: "Kebab", price: 31.48, size: "42oz", type: "Food" },
{ id: 6, name: "Berger", price: 23.83, size: "99oz", type: "Food" },
];
var menu2 = []; // creates a new array to hold the results
for(var i = 0; menu[i]; i++){
if(menu[i].price > 10) menu2[menu2.length] = menu[i]; // If an item has a price greater than 10 then I copy it to the new menu
}
console.log(menu2); // Display the new menu with the filtered data in the console

How to find a value in an array of objects using JavaScript?

I want to:
Find the cheapest and most expensive food and drink.
Find the id and name of drinks and foods if their price is higher than 10.
My attempt:
let menu = [
{ id: 1, name: "Soda",price: 3.12,size: "4oz",type: "Drink" },
{ id: 2, name: "Beer", price: 6.50, size: "8oz", type: "Drink" },
{ id: 3, name: "Margarita", price: 12.99, size: "12oz", type: "Drink" },
{ id: 4, name: "Pizza", price: 25.10, size: "60oz", type: "Food" },
{ id: 5, name: "Kebab", price: 31.48, size: "42oz", type: "Food" },
{ id: 6, name: "Berger", price: 23.83, size: "99oz", type: "Food" }
]
I would be happy and thankful if anybody could help.Thanks in Advanced.
here is an example :
let menu = [
{ id: 1, name: "Soda",price: 3.12,size: "4oz",type: "Drink" },
{ id: 2, name: "Beer", price: 6.50, size: "8oz", type: "Drink" },
{ id: 3, name: "Margarita", price: 12.99, size: "12oz", type: "Drink" },
{ id: 4, name: "Pizza", price: 25.10, size: "60oz", type: "Food" },
{ id: 5, name: "Kebab", price: 31.48, size: "42oz", type: "Food" },
{ id: 6, name: "Berger", price: 23.83, size: "99oz", type: "Food" }
];
function getCheapest(array) {
return Math.min(...array.map(item => item.price));
}
function getExpensive(array) {
return Math.max(...array.map(item => item.price));
}
function getFoodsAndDrinksMoreThan(array, minVal = 10){
return array.filter(item => item.price > minVal).map(item => ({id: item.id, name: item.name}));
}
console.log(getCheapest(menu));
console.log(getExpensive(menu));
console.log(getFoodsAndDrinksMoreThan(menu));
The first one could be achieved with Array.prototype.reduce by comparing the first and second argument of the function you pass into it and returning the smaller one.
For 2. that sounds like a case for Array.prototype.filter to me.
Let me know if you need more guidance.

JavaScript Array Filtering and Mapping Problem. How to do nesting filtering?

Suppose, I have an array.
const arr = [
{
category: 'Diner',
item: [
{name: 'Chicken Rice', price: 200},
{name: 'Mutton Rice', price: 300},
],
},
{
category: 'Breakfast',
item: [
{name: 'Tea Bisuit', price: 100},
{name: 'Bread Butter', price: 300},
{name: 'Green Tea', price: 80},
],
},
];
How can I filter the array according to the item name?
For example, how can I filter the array with the item name Green Tea?
Output must be like this:
arr = [
{
category: 'Breakfast',
item: [
{name: 'Green Tea', price: 80},
],
},
];
You could map through arr, with each element, filter item to which match the term
After that, filter the arr again to reject the elements whose item is empty
const arr = [ { category: "Diner", item: [ { name: "Chicken Rice", price: 200 }, { name: "Mutton Rice", price: 300 }, ], }, { category: "Breakfast", item: [ { name: "Tea Bisuit", price: 100 }, { name: "Bread Butter", price: 300 }, { name: "Green Tea", price: 80 }, ], }, ]
const term = "Green Tea"
const res = arr
.map((categoryAndItems) => ({
category: categoryAndItems.category,
item: categoryAndItems.item.filter((item) => item.name === term),
}))
.filter((categoryAndItems) => categoryAndItems.item.length > 0)
console.log(res)

Get element, remove duplicates and count total of each

I have the following list (object):
var data = [{
id: 1,
type: 'smartphone',
details: [{
brand: 'Samsung',
model: 'Galaxy A5'
}]
},
{
id: 2,
type: 'smartphone',
details: [{
brand: 'iPhone',
model: '6 plus'
}]
},
{
id: 3,
type: 'smartphone',
details: [{
brand: 'Samsung',
model: 'Galaxy A5'
}]
},
{
id: 4,
type: 'smartphone',
details: [{
brand: 'iPhone',
model: '7 plus'
}]
},
{
id: 5,
type: 'phone',
details: [{
brand: 'Nokia',
model: '3310'
}]
},
{
id: 6,
type: 'smartphone',
details: [{
brand: 'Samsung',
model: 'Galaxy A5'
}]
},
{
id: 7,
type: 'smartphone',
details: [{
brand: 'iPhone',
model: '6 plus'
}]
}
]
I try to show on the page a filtered list of phones and with the total amount of them using javascript/ angular
So on my page I want the following result:
Phone: Samsung, Model: Galaxy A5, Total: 3
Phone: iPhone, Model: 7 plus, Total: 1
Phone: iPhone, Model: 6 plus, Total: 2
Phone: Nokia, Model: 3310, Total: 1
I will render it using ngFor but not quite sure how to filter and count total of each model at the same time.
Thanks in advance!
You can use reduce() method to transform your data to one object or array of objects and also calculate total for each model and brand.
var data = [{"id":1,"type":"smartphone","details":[{"brand":"Samsung","model":"Galaxy A5"}]},{"id":2,"type":"smartphone","details":[{"brand":"iPhone","model":"6 plus"}]},{"id":3,"type":"smartphone","details":[{"brand":"Samsung","model":"Galaxy A5"}]},{"id":4,"type":"smartphone","details":[{"brand":"iPhone","model":"7 plus"}]},{"id":5,"type":"phone","details":[{"brand":"Nokia","model":"3310"}]},{"id":6,"type":"smartphone","details":[{"brand":"Samsung","model":"Galaxy A5"}]},{"id":7,"type":"smartphone","details":[{"brand":"iPhone","model":"6 plus"}]}]
var result = data.reduce((r, {details}) => {
details.forEach(({brand, model}) => {
let key = `${brand}|${model}`;
if(!r[key]) r[key] = {phone: brand, model, total: 0}
r[key].total++;
})
return r;
}, {})
console.log(Object.values(result))
You can use reduce to remove the duplicates..
var data = [{
id: 1,
type: 'smartphone',
details: [{
brand: 'Samsung',
model: 'Galaxy A5'
}]
},
{
id: 2,
type: 'smartphone',
details: [{
brand: 'iPhone',
model: '6 plus'
}]
},
{
id: 3,
type: 'smartphone',
details: [{
brand: 'Samsung',
model: 'Galaxy A5'
}]
},
{
id: 4,
type: 'smartphone',
details: [{
brand: 'iPhone',
model: '7 plus'
}]
},
{
id: 5,
type: 'phone',
details: [{
brand: 'Nokia',
model: '3310'
}]
},
{
id: 6,
type: 'smartphone',
details: [{
brand: 'Samsung',
model: 'Galaxy A5'
}]
},
{
id: 7,
type: 'smartphone',
details: [{
brand: 'iPhone',
model: '6 plus'
}]
}
]
var reduced = data.reduce((acc, eachElem) => {
var foundIndex = acc.findIndex((e) => {
return eachElem.type == e.type && eachElem.details[0].brand == e.details[0].brand && eachElem.details[0].model == e.details[0].model;
});
if (foundIndex === -1) {
eachElem["count"] = 1;
acc.push(eachElem);
}
else {
acc[foundIndex]['count']++
}
return acc;
}, [])
console.log(reduced);

Javascript adding to an object (used as an array)

I have an object with the below structure and I'm wondering how to add a line to it.
var itemList = {
'1': { type: "car", make: "audi", price: 500, number: 10, description: "a car" },
'2': { type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
};
line to add:
'3': { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" },
and I would like to add another line to this array but I have no clue how to even start so any help is welcome!
I assume you need to calculate the next insertion point.
Not sure why you're not using an actual Array, but if you have a fixed offset from 0 and a sequential enumeration from there, you can use Object.keys to get the number of keys for the next index.
const offset = 1;
var itemList = {
'1': { type: "car", make: "audi", price: 500, number: 10, description: "a car" },
'2': { type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
};
itemList[Object.keys(itemList).length + offset] = { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" }
console.log(itemList);
But again, this presumes there's some good reason for using this kind of data structure instead of an Array.
And note that the offset can be pre-calculated if it's not known in advance, again assuming the rest of the keys are sequential integers.
var itemList = {
'1': { type: "car", make: "audi", price: 500, number: 10, description: "a car" },
'2': { type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
};
const offset = Math.min(Object.keys(itemList).length, ...Object.keys(itemList));
itemList[Object.keys(itemList).length + offset] = { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" }
console.log(itemList);
Or if you don't have a sequential set of numeric keys, but need to add one after the current highest key, you can do this:
var itemList = {
'1': { type: "car", make: "audi", price: 500, number: 10, description: "a car" },
'2': { type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
};
const next = Math.max(-1, ...Object.keys(itemList)) + 1;
itemList[next] = { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" }
console.log(itemList);
Surprised none of the other answers have simply suggested switched to an actual array (of objects), because then you could simply push a new object into it.
You can then take advantage of all the useful array methods that are available to change/filter your data.
var itemList = [
{ type: "car", make: "audi", price: 500, number: 10, description: "a car" },
{ type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
];
const newItem = { type: "kite", make: "adobe", price: 10, number: 12, description: "Woo!" }
itemList.push(newItem);
console.log(itemList);
As rmlan says this is not an array, but an object. You could add your new "item" in the following way:
itemList['3'] = { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" };
You can just use the index operator like so:
var itemList = {
'1': { type: "car", make: "audi", price: 500, number: 10, description: "a car" },
'2': { type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
};
itemList[3] = { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" };
console.log(itemList);

Categories