How to add aditional object property in array of objects? - javascript

I'm trying to dynamically add additional property in the existing object.
This is what I have:
let items = [
{name: 'Carlsberg', category: 'Beer', price: '4.99'},
{name: 'Smirnoff', category: 'Vodka', price: '28.99'},
{name: 'Miller Lite', category: 'Beer', price: '7.99'}
]
These are the object properties which I wish to add:
categories:{
beerCounter:2,
vodkaCounter:1,
}
And what I want is to dynamically add additional properties of an object to look like this:
items = [
{name: 'Carlsberg', category: 'Beer', price: '4.99', counter: categories.beerCounter},
{name: 'Smirnoff', category: 'Vodka', price: '28.99', counter: categories.vodkaCounter},
{name: 'Miller Lite', category: 'Beer', price: '7.99', counter: categories.beerCounter}
]

Using Array.forEach:
let items = [
{name: 'Carlsberg', category: 'Beer', price: '4.99'},
{name: 'Smirnoff', category: 'Vodka', price: '28.99'},
{name: 'Miller Lite', category: 'Beer', price: '7.99'}
];
const categories = {
beerCounter: 2,
vodkaCounter: 1,
};
items.forEach(item => {
item.counter = item.category === 'Beer' ? categories.beerCounter : categories.vodkaCounter;
})
console.table(items);

You could just iterate your array using forEach, setting the counter property using the lower-cased category value for each item:
let items = [{
name: 'Carlsberg', category: 'Beer', price: '4.99'
},
{
name: 'Smirnoff', category: 'Vodka', price: '28.99'
},
{
name: 'Miller Lite', category: 'Beer', price: '7.99'
}
]
let categories = {
beerCounter: 2,
vodkaCounter: 1,
}
items.forEach(i => i.counter = categories[`${i.category.toLowerCase()}Counter`])
console.log(items)

You can do this with the Array.forEach() method.
I advise you to do this with a regex, it avoids keyboard errors if your category ever comes in all lowercase or all uppercase, or even a mixture of the two, sometimes our fingers wander from typing code haha
let items = [
{name: 'Carlsberg', category: 'Beer', price: '4.99'},
{name: 'Smirnoff', category: 'Vodka', price: '28.99'},
{name: 'Miller Lite', category: 'Beer', price: '7.99'}
]
const categories = {
beerCounter: 2,
vodkaCounter: 1,
};
items.forEach(item => {
if (/^beer/i.test(item.category)) {
item.counter = categories.beerCounter;
}
if (/^vodka/i.test(item?.category)) {
item.counter = categories.vodkaCounter;
}
});
console.log(items);
Good luck dude !

let items = [
{name: 'Carlsberg', category: 'Beer', price: '4.99'},
{name: 'Smirnoff', category: 'Vodka', price: '28.99'},
{name: 'Miller Lite', category: 'Beer', price: '7.99'}
]
items.forEach((item) => {
if(item.category === 'Beer'){
item.categories = categories.beerCounter
}
})

You can use map or forEach
let items = [
{name: 'Carlsberg', category: 'Beer', price: '4.99'},
{name: 'Smirnoff', category: 'Vodka', price: '28.99'},
{name: 'Miller Lite', category: 'Beer', price: '7.99'}
]
const categories = {
beerCounter:2,
vodkaCounter:1,
}
items.forEach(item=>{
if(item.category === 'Beer')
item.counter = categories.beerCounter;
if(item.category === 'Vodka')
item.counter = categories.vodkaCounter;
})
console.log(items);

Related

Sort aray of objects by another array of objects reference

I need some help to sort this data out, i have an array of products and i need to sort and display by settings configuration. The output must have the same order as settings array (index) and if display is true. Thanks in advance. This is what i tryed:
var products = [
{id: 0, name: 'Chocolate', category: 'Sweet'},
{id: 1, name: 'Almendras', category: 'Fruit'},
{id: 2, name: 'Nueces', category: 'Fruit'},
{id: 3, name: 'Mermelada', category: 'Jam'},
{id: 4, name: 'Alfajor', category: 'Sweet'},
{id: 5, name: 'Queso', category: 'UwU'},
{id: 6, name: 'Arandanos', category: 'Fruit'},
{id: 7, name: 'Maracuya', category: 'Fruit'}
];
let settings = [
{
name: 'Fruit',
display: true
},
{
name: 'Jam',
display: false
},
{
name: 'Sweet',
display: true
},
{
name: 'UwU',
display: true
}
]
let group = products.reduce((r, a) => {
r[a.category] = [...r[a.category] || [], a];
return r;
}, {});
let arrangedProducts = Object.keys(group);
console.log(group);
console.log(arrangedProducts);
This is my expected output:
/*
expected result = [
[
{id: 1, name: 'Almendras', category: 'Fruit'},
{id: 2, name: 'Nueces', category: 'Fruit'},
{id: 6, name: 'Arandanos', category: 'Fruit'},
{id: 7, name: 'Maracuya', category: 'Fruit'}
],
[
{id: 0, name: 'Chocolate', category: 'Sweet'},
{id: 4, name: 'Alfajor', category: 'Sweet'}
],
[
{id: 5, name: 'Queso', category: 'UwU'}
]
]
*/
Solution
Making of groups
Apply settings and retrieve the result
const products = [
{ id: 0, name: "Chocolate", category: "Sweet" },
{ id: 1, name: "Almendras", category: "Fruit" },
{ id: 2, name: "Nueces", category: "Fruit" },
{ id: 3, name: "Mermelada", category: "Jam" },
{ id: 4, name: "Alfajor", category: "Sweet" },
{ id: 5, name: "Queso", category: "UwU" },
{ id: 6, name: "Arandanos", category: "Fruit" },
{ id: 7, name: "Maracuya", category: "Fruit" },
];
const productsGroup = products.reduce((r, a) => {
r[a.category] = [...(r[a.category] || []), a];
return r;
}, {});
function applySettings(settings) {
return settings.filter((s) => s.display).map((s) => productsGroup[s.name]);
}
console.log(
applySettings([
{
name: "Fruit",
display: true,
},
{
name: "Jam",
display: false,
},
])
);
console.log(
applySettings([
{
name: "Fruit",
display: true,
},
{
name: "Sweet",
display: true,
},
{
name: "UwU",
display: true,
},
])
);
You can filter your settings list based on the display property and then use Array.map to return a list of objects in products that match the category:
const products = [
{id: 0, name: 'Chocolate', category: 'Sweet'},
{id: 1, name: 'Almendras', category: 'Fruit'},
{id: 2, name: 'Nueces', category: 'Fruit'},
{id: 3, name: 'Mermelada', category: 'Jam'},
{id: 4, name: 'Alfajor', category: 'Sweet'},
{id: 5, name: 'Queso', category: 'UwU'},
{id: 6, name: 'Arandanos', category: 'Fruit'},
{id: 7, name: 'Maracuya', category: 'Fruit'}
];
const settings = [
{ name: 'Fruit', display: true },
{ name: 'Jam', display: false },
{ name: 'Sweet', display: true },
{ name: 'UwU', display: true }
];
const result = settings
.filter(c => c.display)
.map(c => products.filter(o => o.category == c.name));
console.log(result);
Note that this code does filter the products array for each settings value that has display:true, so may be slow for large arrays. However filter is pretty low overhead and testing with OP's sample data shows this to run 3x the speed of the reduce version; and with a larger products array (99 entries) to run 10x faster.
This should be pretty quick, because it continues on to the next iteration without executing the inner loop when display is false:
var products = [
{id: 0, name: 'Chocolate', category: 'Sweet'},
{id: 1, name: 'Almendras', category: 'Fruit'},
{id: 2, name: 'Nueces', category: 'Fruit'},
{id: 3, name: 'Mermelada', category: 'Jam'},
{id: 4, name: 'Alfajor', category: 'Sweet'},
{id: 5, name: 'Queso', category: 'UwU'},
{id: 6, name: 'Arandanos', category: 'Fruit'},
{id: 7, name: 'Maracuya', category: 'Fruit'}
];
let settings = [
{
name: 'Fruit',
display: true
},
{
name: 'Jam',
display: false
},
{
name: 'Sweet',
display: true
},
{
name: 'UwU',
display: true
}
];
function sortProducts(){
const r = [];
let i = -1;
for(let s of settings){
if(!s.display){
continue;
}
i++;
for(let o of products){
if(s.name === o.category){
if(r[i]){
r[i].push(o);
}
else{
r.push([o]);
}
}
}
}
return r;
}
console.log(sortProducts());

Count the number of items in each category within a JavaScript object

I have an array containing several hundred objects, each of which has a category. I wish to return an object that lists out the categories with a count of the number of items for each category.
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
How would I loop through the object and create a new object that contains just the two categories and how many of each per category?
Desired output:
{vehicle: 4, animal: 3}
Code:
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const final = {};
arr.forEach((v) => {
const tst = v.category;
console.log(tst);
if (tst in final){
console.log('found one');
}
});
//console.log(final);
You can use reduce
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const categories = arr.reduce((acc, cur) => {
acc[cur.category] = (acc[cur.category] || 0) + 1
return acc;
}, {})
console.log(categories)
edit:
Now, after a year a would wrt this like that
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const categories = arr.reduce((acc, cur) => Object.assign(acc, {
[cur.category]: (acc[cur.category] || 0) + 1,
}), {})
console.log(categories)
It looks like the category will always exist, so you don't need to check whether it exists, but what it contains; take what it contains and increment that property on the final object:
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const final = {};
for (const { category } of arr) {
final[category] = (final[category] || 0) + 1;
};
console.log(final);
You have the right idea regarding looping over the array and checking if the category was already encountered. What you're missing is initializing a counter when you find a new category and incrementing it the next time that category is encountered:
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const final = {};
arr.forEach((v) => {
const cat = v.category;
if (cat in final) {
final[cat]++;
} else {
final[cat] = 1;
}
});
console.log(final);
const arr = [
{ id: 1, name: 'ford', category: 'vehicle' },
{ id: 2, name: 'pig', category: 'animal' },
{ id: 3, name: 'dog', category: 'animal' },
{ id: 4, name: 'chev', category: 'vehicle' },
{ id: 5, name: 'cat', category: 'animal' },
{ id: 6, name: 'jeep', category: 'vehicle' },
{ id: 7, name: 'honda', category: 'vehicle' },
]
// this will hold the results
const result = {}
for (const item of arr) {
// we have not encountered such category before
if (result[item.category] === undefined) {
// setting this category to 1
result[item.category] = 1
// we encountered such category before
} else {
// addint +1 to it
result[item.category] += 1
}
}
console.log(result)

Javascript Object Array Sorting Issue

I have a JavaScript array of objects to sort and arrange it as a new object array preserving the order.
My array of objects. I get them ordered in the way that I want. The index of the objects are 0,1 & 2 in this.
[{0: {name: 'Joel', age:25, id: 2}}, {1: {name: 'Sam', age: 23, id: 4}}, {2: {name: 'Tim', age:27, id: 3}}]
What I want is to make 'id' the index value. And I want it in ascending order of the 'name' (Preserving the above order)
[{2: {name: 'Joel', age:25, id: 2}}, {4: {name: 'Sam', age: 23, id: 4}}, {3: {name: 'Tim', age:27, id: 3}}]
I tried using this function.
for (i in members) {
member[members[i].id] = members[i];
}
But it failed. The output was
[{}, {}, {name: "Joel", age:25, id: 2}, {name: "Tim", age:27, id: 3}, {name: "Sam", age: 23, id: 4}]
I tried using forEach and sort methods too. But all failed.
Is there any way to accomplish this in JavaScript.
You can do it with help of map and sort.
let obj = [{0: {name: 'Joel', age:25, id: 2}}, {1: {name: 'Sam', age: 23, id: 4}}, {2: {name: 'Tim', age:27, id: 3}}]
let op = obj.map((e,index)=>{
return{
[e[index].id] : e[index]
}
}).sort((a,b)=> Object.keys(a) - Object.keys(b))
console.log(op)

Sort object array by looking at another array order

I'm trying to sort an object array by looking at another arrays order, my first array is something like this
["HV001O3XL", "HV001OSML", "HV001OLGE"]
and my object array is like :
[{productcode: "HV001OSML", price: 6, qty: "2", desc: "HV001 WAISTCOAT ORN", stock: "138"},{productcode: "HV001OLGE", price: 6, qty: "1", desc: "HV001 WAISTCOAT ORN", stock: "271"},{productcode: "HV001O3XL", price: 6, qty: "1", desc: "HV001 WAISTCOAT ORN", stock: "1112"}]
I would like to re-shuffle the object array so that the object.productcode matched the first array, HV001O3XL being first instead of HV001OSML etc. Is this possible in angular or javascript?
const objs = [
{
productcode: "HV001OSML",
price: 6,
qty: "2",
desc: "HV001 WAISTCOAT ORN",
stock: "138"
},
{
productcode: "HV001OLGE",
price: 6,
qty: "1",
desc: "HV001 WAISTCOAT ORN",
stock: "271"
},
{
productcode: "HV001O3XL",
price: 6,
qty: "1",
desc: "HV001 WAISTCOAT ORN",
stock: "1112"
}
];
const result = [
"HV001O3XL",
"HV001OSML",
"HV001OLGE"
].map((key) => objs.find(item => item.productcode === key));
console.log(result);
const orders = ['a', 'b', 'c', 'd'];
let objects = [{
code: 'd'
}, {
code: 'c'
}, {
code: 'a',
}, {
code: 'b'
}]
objects.sort((a, b) => orders.indexOf(a.code) - orders.indexOf(b.code));
console.log(objects);

Lodash, taking objects fulfilling requirements

Example:
Animals = [{Name: 'Dog', Id: 0},
{Name: 'Cat', Id: 1},
{Name: 'Mouse', Id: null}]
How to take all objects where Id isn't null into new array?
Expected output:
NewArray = [{Name: 'Dog', Id: 0},
{Name: 'Cat', Id: 1}]
Try with _.filter
var Animals = [{Name: 'Dog', Id: 0},{Name: 'Cat', Id: 1},{Name: 'Mouse', Id:null}]
var newArray =_.filter(Animals ,a=> a.Id != null)
console.log(newArray)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.2/lodash.min.js"></script>

Categories

Resources