How to check for at least one object inside another object - javascript

I need to validate a form field.
this is the categories field inside my form.
categories = {
category1: [
{ id: 1, quantity: 0 },
{ id: 2, quantity: 0 }
],
category2: [
{ id: 3, quantity: 0 },
{ id: 4, quantity: 0 }
],
category3: [
{ id: 5, quantity: 0 },
{ id: 6, quantity: 0 }
]
}
this is how I check if AT LEAST ONE array element passes a test inside EACH category.
for (const category in categories) {
let theOne = categories[category].some(product => product.quantity !== 0);
}
this way the form will be valid if at least one quantity inside EACH category will hold a value of 1.
// I DONT WANT THIS
categories = {
category1: [
{ id: 1, quantity: 1 }, // at least one quantity value is 1
{ id: 2, quantity: 0 }
],
category2: [
{ id: 3, quantity: 1 }, // at least one quantity value is 1
{ id: 4, quantity: 0 }
],
category3: [
{ id: 5, quantity: 1 }, // at least one quantity value is 1
{ id: 6, quantity: 0 }
]
}
// I NEED THIS
categories = {
category1: [
{ id: 1, quantity: 1 }, // at least one quantity value is 1
{ id: 2, quantity: 0 }
],
category2: [
{ id: 3, quantity: 0 }, // not needed
{ id: 4, quantity: 0 }
],
category3: [
{ id: 5, quantity: 0 }, // not needed
{ id: 6, quantity: 0 }
]
}
how is it possible to make it work for at least one category ?

That is to check them all:
const categories = {
category1: [{ id: 1, quantity: 0 }],
category2: [{ id: 2, quantity: 1 }],
category3: [{ id: 3, quantity: 0 }]
};
const didIPass = Object.values(categories).some((category) => {
return category.some((subCategory) => subCategory.quantity !== 0);
});
console.log('Did I pass?', didIPass);
That is to check inside each specifically:
Object.entries(categories).forEach((entry) => {
const key = entry[0];
const value = entry[1];
const didIPass = value.some((subCategory) => subCategory.quantity !== 0);
console.log(`Did ${key} pass? ${didIPass}`);
});
Will produce the output:
Did I pass? true
Did category1 pass? false
Did category2 pass? true
Did category3 pass? false

Related

How can I access this property in my dictionary in js?

I thought I understood how to loop through a dictionary, but my loop is wrong. I try to access the name of each sub item but my code does not work.
Here is what I did:
list = [
{
title: 'Groceries',
items: [
{
id: 4,
title: 'Food',
cost: 540 ,
},
{
id: 5,
title: 'Hygiene',
cost: 235,
},
{
id: 6,
title: 'Other',
cost: 20,
},
],
}];
function calculateCost(){
let total = 0;
Object.keys(list).forEach((k) => { for (i in k.items) { total += i.data; } });
console.log(total);
return total;
}
Your list is an array includes 1 object and this object has two properties title and items the items here is an array of objects each one of these objects has property cost so to calculate the total cost you need to loop through items array, here is how you do it:
let list = [
{
title: 'Groceries',
items: [
{
id: 4,
title: 'Food',
cost: 540 ,
},
{
id: 5,
title: 'Hygiene',
cost: 235,
},
{
id: 6,
title: 'Other',
cost: 20,
},
],
}];
function calculateCost(){
let total = 0;
list[0].items.forEach(el => {
total += el.cost;
})
console.log(total)
return total;
}
calculateCost();
Your list is an Array, not an Object.
Instead of Object.keys() use Array.prototype.reduce:
const calculateCost = (arr) => arr.reduce((tot, ob) =>
ob.items.reduce((sum, item) => sum + item.cost, tot), 0);
const list = [
{
title: 'Groceries',
items: [
{id: 4, title: 'Food', cost: 10},
{id: 5, title: 'Hygiene', cost: 20},
{id: 6, title: 'Other', cost: 30}
]
}, {
title: 'Other',
items: [
{id: 8, title: 'Scuba gear', cost: 39}
],
}
];
console.log(calculateCost(list)); // 99
Expanding on #Roko's and #mmh4all's answers, the following code adds several verification statements to handle cases where a deeply nested property in your data is not what you expect it to be.
const calculateCost = (orders) => {
let listOfCosts = [];
// For each 'order' object in the 'orders' array,
// add the value of the 'cost' property of each item
// in the order to 'listOfCosts' array.
orders.forEach(order => {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
if (!Array.isArray(order.items)) { return; }
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseFloat
const orderCostArr = order.items.map(item =>
isNaN(item.cost) ? 0 : parseFloat(item.cost, 10));
if (orderCostArr.length === 0) { return; }
// Concatenate 'orderCostArr' to the 'listOfCosts' array
//listOfCosts = listOfCosts.concat(orderCostArry);
// Alternate approach is to use the spread syntax (...) to
// push the items in the array returned by 'order.items.map()'
// into the 'listOfCosts' array.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
listOfCosts.push(...orderCostArr);
});
// Use the 'reduce' method on the 'listOfCosts' array
// to get the total cost.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
const totalCost = listOfCosts.reduce(
(accumulator, currentValue) => accumulator + currentValue, 0);
return totalCost;
};
const list = [
{
title: 'Groceries',
items: [
{ id: 4, title: 'Food', cost: 10 },
{ id: 3, title: 'Baked goods', cost: 20 },
{ id: 5, title: 'Hygiene', cost: 0 },
{ id: 6, title: 'Other' }
]
}, {
title: 'Gear',
items: {},
}, {
title: 'Accessories',
items: [],
}, {
title: 'Bags',
}, {
title: 'Other',
items: [
{ id: 10, title: 'Scuba gear', cost: "5" },
{ id: 8, title: 'Scuba gear', cost: "err" },
{ id: 9, title: 'Scuba gear', cost: 59 }
],
}
];
console.log(calculateCost(list)); // 94

Compare two arrays javascript

I'm working on puppeteer in nike website.
I'm getting the sizes and stock and showing it as an array,
{ sku: 72961, skuname: 'Talla: 6 - Color: Azul', quantity: 2 },
{ sku: 72962, skuname: 'Talla: 6.5 - Color: Azul', quantity: 4 },
{ sku: 72963, skuname: 'Talla: 7 - Color: Azul', quantity: 5 },
{ sku: 72964, skuname: 'Talla: 7.5 - Color: Azul', quantity: 7 },
{ sku: 72965, skuname: 'Talla: 8 - Color: Azul', quantity: 6 },
{ sku: 72966, skuname: 'Talla: 8.5 - Color: Azul', quantity: 5 },
{ sku: 72967, skuname: 'Talla: 9 - Color: Azul', quantity: 8 },
{ sku: 72968, skuname: 'Talla: 9.5 - Color: Azul', quantity: 8 },
{ sku: 72969, skuname: 'Talla: 10 - Color: Azul', quantity: 6 },
{ sku: 72970, skuname: 'Talla: 10.5 - Color: Azul', quantity: 4 },
{ sku: 72971, skuname: 'Talla: 11 - Color: Azul', quantity: 1 },
{ sku: 72972, skuname: 'Talla: 11.5 - Color: Azul', quantity: 2 }
]
That is refreshing each 10 seconds so I'd like to find a way that the last array is compared to the previous to know if a new Size or quantity is added
My code
const pagina = "https://nike.cl"
const producto = "/dm0121-400-nike-dunk-low-retro-qs/p"
const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900});
while (true) {
await page.goto(pagina + producto, { waitUntil: 'networkidle2' },);
var SKU = await page.evaluate("skuJson_0")
let filter = SKU.skus.filter( d => d.availablequantity > 0)
var SKUfiltered = filter.map(function(d){
return{
sku: d.sku,
skuname: d.skuname,
quantity: d.availablequantity
}})
console.log(SKUfiltered)
await page.waitForTimeout(10000)
I think the best solution is store the SKU data to check if exists previously and if the value are equals.
If the value pass the two checks you could store it in your "SKU register".
As next step, you could make another checks to filter the value. In your case only check if the quantity is zero.
As a complement, if you get many SKU and store a huge maybe you reach the memory limit. So you could remove it if the array is too big. To make that you could create an Array to store the values in order and remove if you reach some limit like 1000 elements.
In the next example, I simulate get the data in each getSKU execution. You must adapt the code to your solution:
// == FAKE DATA ==
let res_i = 0;
const res_data = [
[
{ sku: 1, skuname: "1", quantity: 0 }, // empty
{ sku: 2, skuname: "2", quantity: 1 },
],
[
{ sku: 1, skuname: "1", quantity: 5 },
{ sku: 2, skuname: "2", quantity: 1 }, // same quantity
{ sku: 3, skuname: "3", quantity: 0 }, // empty
],
[
{ sku: 1, skuname: "1", quantity: 0 }, // empty
{ sku: 3, skuname: "3", quantity: 3 },
{ sku: 4, skuname: "4", quantity: 3 },
],
];
// == END FAKE DATA ==
// An array to save the lastest SKU and a Map to store important values
const SKURegLog = [];
const SKURegdata = new Map();
// A funtion to simulate the data
function getSKU() {
const SKU = res_data[res_i++]; // Simulate the incoming data
return SKU.filter((v) => {
// Get the current SKU in the register
const curSKU = SKURegdata.get(v.sku);
// If exists and the quantity is the same, discard
if (curSKU !== undefined && curSKU.quantity === v.quantity) {
return false;
}
// If the SKU not exists in register add to the array
if (curSKU === undefined) {
SKURegLog.push(v.sku);
}
// Include the SKU in the register. If the array reach
// the limit (1000) delete the olders
SKURegdata.set(v.sku, {quantity: v.quantity});
if (SKURegLog.length > 1000) {
const oldSKU = SKURegLog.shift();
SKURegdata.delete(oldSKU);
}
// Check the current quantity
if (v.quantity === 0) {
return false;
}
// Include the SKU
return true;
});
}
console.log(getSKU());
console.log(getSKU());
console.log(getSKU());
console.log("= Register data:");
console.log(SKURegLog);
console.log(SKURegdata);
Output:
1: [ { sku: 2, skuname: '2', quantity: 1 } ]
2: [ { sku: 1, skuname: '1', quantity: 5 } ]
3: [ { sku: 3, skuname: '3', quantity: 3 }, { sku: 4, skuname: '4', quantity: 3 }]
== Register data:
[ 1, 2, 3, 4 ]
Map(4) {
1 => { quantity: 0 },
2 => { quantity: 1 },
3 => { quantity: 3 },
4 => { quantity: 3 }
}

filter array of objects by methods of another array of objects [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I am making a food delivery app and I have two different array of objects. One of them is cartItems and the other is foodItems. The arrays can be of different sizes. So what do I want to loop over each array and check
if the ids of both the array match.
Note I want to check if the quantity exists then increment it by the new quantity else simply add a new quantity
check if itemDetails exists in foodItems array and if it exists, check if the price of cartItems matches of that foodItem, then update the cartItems object, else remove them.
if itemDetails does not exist then update the quantity of the item.
Update
If there are two items with similar id and price, the quantities should be added
Here is my cartItems:
let cartItems = [
{ id: 1, price: 120, quantity: 7 },
{ id: 2, price: 70, quantity: 4 },
{ id: 1, price: 70, quantity: 3 },
{ id: 3, price: 60, quantity: 1 },
{id: 1, price: 120, quantity: 2}
];
Here is my foodItems
let foodItems = [
{
id: 1,
name: "chicken",
itemDetails: [
{
price: 120,
details: "2 pcs of chicken biryani"
},
{
price: 70,
details: "1 pcs of chicken biryani"
}
],
},
{
id: 2,
name: "Mutton",
itemDetails: [
{
price: 120,
details: "Two pieces of mutton biryani",
},
{
price: 70,
details: "one pcs of mutton biryani"
},
],
},
{ id: 3, name: "Ice Cream", price: 60 },
];
This is my desired output
let filteredArrayOuput = [
{
id: 1,
name: "Chicken Biryani",
itemDetails: [
{
price: 120,
details: "Two pieces of chicken Biryani",
},
],
quantity: 7,
},
{
id: 2,
name: "Mutton Biryani",
itemDetails: [
{
price: 70,
details: "Two pieces of mutton biryani",
},
],
quantity: 4,
},
{
id: 1,
price: "Chicken Biryani",
quantity: 3,
itemDetails: [
{
price: 70,
details: "Two pieces of Chicken Biryani",
},
],
},
{ id: 3, price: 60, quantity: 1 },
];
This is what I have done till now
const filterFunc = (arr, price) => {
let filtered = arr.filter((item) => {
return item.price == price;
});
return filtered;
};
const filterArray = (arr1, arr2) => {
const filtered = arr2.filter((el) => {
let arr = arr1.find(({ id, quantity, price }) => {
if (el.id === id) {
if (el.itemDetails !== undefined && el.itemDetails.length !== 0) {
let itemDetails = el.itemDetails;
return (
(el.quantity = quantity),
(el.itemDetails = filterFunc(itemDetails, price))
);
} else {
return (el.quantity = quantity);
}
}
});
return arr;
});
return filtered;
};
console.log(filterArray(cartItems, foodItems))
You can check the below code.
Find existingFoodItem from FoodItems array
Find priceObj by comparing price
return new object with price details if itemDetails exists (checking with ?), else without price if no itemDetails exists.
let cartItems = [
{ id: 1, price: 120, quantity: 7 },
{ id: 1, price: 120, quantity: 1 },
{ id: 2, price: 70, quantity: 4 },
{ id: 1, price: 70, quantity: 3 },
{ id: 3, price: 60, quantity: 1 },
];
let foodItems = [
{
id: 1,
name: "chicken",
itemDetails: [
{
price: 120,
details: "2 pcs of chicken biryani"
},
{
price: 70,
details: "1 pcs of chicken biryani"
}
],
},
{
id: 2,
name: "Mutton",
itemDetails: [
{
price: 120,
details: "Two pieces of mutton biryani",
},
{
price: 70,
details: "one pcs of mutton biryani"
},
],
},
{ id: 3, name: "Ice Cream", price: 60 },
];
let result = [];
cartItems.forEach(cart => {
let esitingItem = result.find(r => r.id === cart.id && r.itemDetails.find(i => i.price === cart.price));
if(esitingItem){
esitingItem.quantity += cart.quantity;
return;
}
let existingFoodItem = foodItems.find(food => food.id === cart.id);
if(existingFoodItem){
let priceObj = existingFoodItem.itemDetails?.find(item => item.price === cart.price);
if(priceObj){
result.push({id:cart.id,name:existingFoodItem.name,itemDetails:[{...priceObj}],quantity:cart.quantity});
}
else{
return result.push({id:cart.id,name:existingFoodItem.name,quantity:cart.quantity});
}
}
});
console.log(result);

Javascript re-order array of object by value

How do I re-order array of object showing below by follow value. If follow value is not -1, move the item below to the item that has the id value same as follow value.
Here is the example.
let charObj = [
{ id: 8, name: 'Catelyn Stark', follow: -1 },
{ id: 7, name: 'Jaime Lannister', follow: 8 },
{ id: 3, name: 'Jon Snow', follow: -1 },
{ id: 4, name: 'Daenerys Targaryen', follow: 7 },
{ id: 5, name: 'Sansa Stark', follow: 4 }
];
Expected output will be;
let charObj = [
{ id: 8, name: 'Catelyn Stark', follow: -1 },
{ id: 7, name: 'Jaime Lannister', follow: 8 },
{ id: 4, name: 'Daenerys Targaryen', follow: 7 },
{ id: 5, name: 'Sansa Stark', follow: 4 },
{ id: 3, name: 'Jon Snow', follow: -1 }
];
Not sure if I can use sort(). What is the best way to re-order this object?
I think this will do what you're asking. I'm sure it could be made more efficient, but unless your list gets quite large that shouldn't make much practical difference. Also, this assumes any character will only have one follower. If that's not the rule, then the function will have to be adjusted.
let charObj = [
{ id: 8, name: "Catelyn Stark", follow: -1 },
{ id: 7, name: "Jaime Lannister", follow: 8 },
{ id: 3, name: "Jon Snow", follow: -1 },
{ id: 4, name: "Daenerys Targaryen", follow: 7 },
{ id: 5, name: "Sansa Stark", follow: 4 }
];
function sortChars(chars) {
let result = [];
let leaders = chars.filter(c => c.follow === -1);
for (let i = 0; i < leaders.length; i++) {
let current = leaders[i];
while (current) {
result.push(current);
let next = charObj.find(c => c.follow === current.id);
current = next;
}
}
return result;
}
console.log(sortChars(charObj));

Compare and reduce complex array of objects

I have a ``dataset which is an array of objects for some items in a database that has the details of how long it will take in estimatedDays for a specific item to be shipped:
items : [
{
id: '1'
shippingMethods: [
{
id: 'STANDARD',
estimatedDays: 3,
},
{
id: 'TWODAY',
estimatedDays: 2,
},
{
id: 'NEXTDAY',
estimatedDays: 1,
},
]
},
{
id: '2'
// same shipping data as above but standard shipping will take 4 estimatedDays
},
{
id: '3'
// same shipping data as above but TWODAY shipping will take 3 estimatedDays
},
]
I am wondering if there is a reduce function that could compare each shippingMethod.id in each item and return a new array back only where shippingMethod.estimatedDays is greatest compared to all items.
So the end array would be an array of objects with (in this case) 3 shipping methods: STANDARD, TWODAY, and NEXTDAY.
Here you go with the reduce method,
reduce
var items = [
{
id: '1',
shippingMethods: [
{
id: 'STANDARD',
estimatedDays: 3
},
{
id: 'TWODAY',
estimatedDays: 2
},
{
id: 'NEXTDAY',
estimatedDays: 1
},
]
},
{
id: '2',
shippingMethods: [
{
id: 'STANDARD',
estimatedDays: 4
},
{
id: 'TWODAY',
estimatedDays: 2
},
{
id: 'NEXTDAY',
estimatedDays: 1
},
]
},
{
id: '3',
shippingMethods: [
{
id: 'STANDARD',
estimatedDays: 3
},
{
id: 'TWODAY',
estimatedDays: 3
},
{
id: 'NEXTDAY',
estimatedDays: 1
},
]
},
];
var outItems = items.reduce(function(accu, curr){
if(curr.shippingMethods) {
if(accu.length > 0) {
for(var i = 0; i < curr.shippingMethods.length; i++) {
var current = curr.shippingMethods[i];
if(accu[i].id === current.id && accu[i].estimatedDays < current.estimatedDays) {
accu[i] = current;
}
}
} else {
accu = curr.shippingMethods;
}
}
return accu;
}, []);
console.log(outItems);

Categories

Resources