How to add random values in an object array Javascript? - javascript

const prod = [{
name: "Sweat",
description: " collection",
price: 150,
},
{
name: "Trousers",
description: "Attire",
price: 243
},
{
name: "T-shirt",
description: "Winter",
},
{
name: "Hoody",
description: "Fashion",
},
{
name: "Pants",
description: "Winter",
},
{
name: "Casual",
description: "Winter",
price: 245,
},
{
name: "Shirt",
description: "Attire",
price: 150,
}
];
Hi, I'm trying to add a random popularity score between 0 - 100, randomly for the products without them using a function.
I've tried to figure out solutions from
https://levelup.gitconnected.com/set-data-structure-in-javascript-62e65908a0e6
and
https://medium.com/front-end-weekly/getting-a-random-item-from-an-array-43e7e18e8796
but still unsure how to add elements to specific indices without the 'popularity' element. Thanks!

Filter the array to the elements you want first, then apply the random number
// function
const addRandomPopularityWhereThereIsNone = products => {
products.filter(p => !p.hasOwnProperty('popularity')).forEach(p => {
p.popularity = Math.floor(Math.random() * 101)
})
}
// call it
addRandomPopularityWhereThereIsNone(products)
Note that this modifies the original array.
For reference:
Array.prototype.filter()
Object.protytype.hasOwnProperty()

Please try the following solution
const products = [{"name":"Pullover Sweat","description":"Winter collection","price":150,"popularity":99},{"name":"Formal Trousers","description":"Attire for men","price":500},{"name":"Winter T-shirt","description":"Winter collection","price":50,"popularity":50},{"name":"New Fashion Hoody","description":"Fashion line","price":200},{"name":"Winter Pants","description":"Winter collection","price":150},{"name":"Casual Coat","description":"Winter collection","price":245,"popularity":78},{"name":"Fine Long Sleeve Shirt","description":"Attire for men","price":150,"popularity":10}];
const output = products.map((product) => {
if ("popularity" in product) {
return { ...product };
}
return { ...product, popularity: generateRandomNumber() };
});
function generateRandomNumber() {
return Math.floor(Math.random() * 100) + 1;
}
console.log(output);
Take a look to array map and the in operator

Use map and nullish coalescing operator (??)
const products = [{"name":"Pullover Sweat","description":"Winter collection","price":150,"popularity":99},{"name":"Formal Trousers","description":"Attire for men","price":500},{"name":"Winter T-shirt","description":"Winter collection","price":50,"popularity":50},{"name":"New Fashion Hoody","description":"Fashion line","price":200},{"name":"Winter Pants","description":"Winter collection","price":150},{"name":"Casual Coat","description":"Winter collection","price":245,"popularity":78},{"name":"Fine Long Sleeve Shirt","description":"Attire for men","price":150,"popularity":10}];
const update = (arr) =>
arr.map(({ popularity, ...product }) => ({
popularity: popularity ?? Math.floor(Math.random() * 100) + 1,
...product,
}));
console.log(update(products));

const products = [{
name: "Pullover Sweat",
description: "Winter collection",
price: 150,
popularity: 99
},
{
name: "Formal Trousers",
description: "Attire for men",
price: 500
},
{
name: "Winter T-shirt",
description: "Winter collection",
price: 50,
popularity: 50
},
{
name: "New Fashion Hoody",
description: "Fashion line",
price: 200
},
{
name: "Winter Pants",
description: "Winter collection",
price: 150
},
{
name: "Casual Coat",
description: "Winter collection",
price: 245,
popularity: 78
},
{
name: "Fine Long Sleeve Shirt",
description: "Attire for men",
price: 150,
popularity: 10
}
];
const addPopularity = products => {
products.filter(p => !p.popularity).map(p => {
p.popularity = Math.floor(Math.random() * 101)
})
return products;
}
console.log(addPopularity(products));

Related

Is there a way to console.log an output only when my loop finishes running and matched no entry

In the code below how do i output try again only when the entire code execution runs and customer's order is not found amongst the product order in the menuItem dictionary.
I want to output this only when customer input doesn't match any product code
let menuItem = {
item_1: {
name: "french burger",
price: 1000,
productCode: 101
},
item_2: {
name: "chicken sharwama",
price: 1500,
productCode: 102
},
item_3: {
name: "pizza",
price: 5000,
productCode: 103
},
item_4: {
name: "beef sharwama",
price: 1500,
productCode: 104
},
item_5: {
name: "smoothie (mix flavor)",
price: 1300,
productCode: 105
}
}
listMenuItem = () => {
for (let i in menuItem) {
console.log(`Order Code: ${menuItem[i].productCode} || ${menuItem[i].name}, ${menuItem[i].price} NGN \n`)
}
}
listMenuItem()
var order = prompt("Enter product code to make your order: ")
console.log(order)
let customerOrder = []
for (let i in menuItem) {
if (menuItem[i].productCode == order) {
customerOrder.push(menuItem[i])
console.log(customerOrder)
console.log(`${menuItem[i].name}, ${menuItem[i].price}`)
} else {
console.log("Product does not exist, try again")
}
}
Your structure makes it harder to use the array methods.
The result is more confusing that it would have been if you just had an object keyed on productCode
let menuItem = {
item_1: {
name: "french burger",
price: 1000,
productCode: 101
},
item_2: {
name: "chicken sharwama",
price: 1500,
productCode: 102
},
item_3: {
name: "pizza",
price: 5000,
productCode: 103
},
item_4: {
name: "beef sharwama",
price: 1500,
productCode: 104
},
item_5: {
name: "smoothie (mix flavor)",
price: 1300,
productCode: 105
}
}
listMenuItem = () => {
for (let i in menuItem) {
console.log(`Order Code: ${menuItem[i].productCode} || ${menuItem[i].name}, ${menuItem[i].price} NGN \n`)
}
}
listMenuItem()
var order = +prompt("Enter product code to make your order: "); // convert the string to number or make the productCode a string in the object
console.log(order)
let customerOrder = Object.entries(menuItem).find(([key,{productCode}]) => productCode === order);
console.log(customerOrder)
if (customerOrder) {
console.log(`I found ${customerOrder[1].name}, ${customerOrder[1].price}`)
}
else {
console.log("Product does not exist, try again")
}

How to loop over a an array that is already inside a map function without duplicating the contents

I have the following code with the following arrays. I want to loop through both of them and pull out some data, and put them inside a final array. I am able to do that, but the contents are duplicated. I tried reading about reduce but don't quite understand it, and am not sure if it's the right solution. I have also setup a jsfiddle
https://jsfiddle.net/anders_kitson/Lcqn6fgd/
var lineItems = [{
id: 'li_1HyhAZHk5l44uIELgsMWqHqB',
object: 'item',
amount_subtotal: 7500,
amount_total: 7500,
currency: 'cad',
description: 'The Spencer',
price: [Object],
quantity: 1
},
{
id: 'li_1HyhAZHk5l44uIELeNUsiZPu',
object: 'item',
amount_subtotal: 7500,
amount_total: 7500,
currency: 'cad',
description: 'The Gertie',
price: [Object],
quantity: 1
}
]
var arr = [{
id: 'prod_IS1wY1JvSv2CJg',
object: 'product',
active: true,
attributes: [],
created: 1606248785,
description: 'Shelf Set',
images: [
'https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq'
],
livemode: false,
metadata: {},
name: 'The Spencer',
statement_descriptor: null,
type: 'service',
unit_label: null,
updated: 1606248785
},
{
id: 'prod_IS299dMnC13Ezo',
object: 'product',
active: true,
attributes: [],
created: 1606249543,
description: 'Shelf Set',
images: [
'https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe'
],
livemode: false,
metadata: {},
name: 'The Gertie',
statement_descriptor: null,
type: 'service',
unit_label: null,
updated: 1606249543
}
];
let productArr = [];
arr.map((item) => {
lineItems.map((line) => {
productArr.push({
image: item.images[0],
name: item.name,
price: line.amount_total,
});
});
});
console.log(productArr);
This is the output I get where you can see the array repeats the values, and I know I have coded it this way I just don't know how to fix it.
[{
image: "https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq",
name: "The Spencer",
price: 7500
}, {
image: "https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq",
name: "The Spencer",
price: 7500
}, {
image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
name: "The Gertie",
price: 7500
}, {
image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
name: "The Gertie",
price: 7500
}]
To Be more clear this is the output that I want
[{
image: "https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq",
name: "The Spencer",
price: 7500
}, {
image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
name: "The Gertie",
price: 7500
},
]
I have tried the suggestion in the comments with the following
let b
arr.map((item) => {
b = lineItems.map((line) => {
return {
image: item.images[0],
name: item.name,
price: line.amount_total,
};
});
});
but it returns the same ones twice
[{
image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
name: "The Gertie",
price: 7500
}, {
image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
name: "The Gertie",
price: 7500
}]
Although not expressed directly in your question, it seems you're looking to do a join in javascript. The only things I see relating the two are 'name' in products and 'description' in the line items. So do a loop join on that.
Here's some sample code using your example but stripped down only to what's relevant:
var lineItems = [
{ amount_total: 7500, description: 'The Spencer' },
{ amount_total: 7500, description: 'The Gertie' }
]
var arr = [
{ images: ['Spencer Image 1'], name: 'The Spencer' },
{ images: ['Gertie Image 1'], name: 'The Gertie' }
]
let joined = arr
.flatMap(a => lineItems.map(li => ({a, li})))
.filter(obj => obj.a.name == obj.li.description)
.map(obj => ({
image: obj.a.images[0],
name: obj.a.name,
price: obj.li.amount_total
}));
console.log(joined);
Being a loop join, it may not be that efficient. To do a hash join is a little more involved. You can look through the source code of my developing project
fluent-data, or it might even be useful to you to use it directly if you can follow the documentation.
You can use a single map call and reference your second lineItems array either by index, if you know that the two arrays are the same length and order
const output = arr.map((o, i) => ({
name: o.name,
image: o.images[0],
price: lineItems[i].amount_total}
));
or by using find() to retrieve the relevant object.
const outputUsingFind = arr.map(o => {
const lineItem = lineItems.find(item => item.description === o.name);
// ** add lineItem valid check here **
return {
name: o.name,
image: o.images[0],
price: lineItem.amount_total};
});
var lineItems = [{amount_subtotal: 7500,amount_total: 700,description: 'The Spencer',},{amount_subtotal: 7500,amount_total: 500,description: 'The Gertie',}];
var arr = [{images: ['spencer image'],name: 'The Spencer',},{images: ['gertie image'],name: 'The Gertie'}];
// since your arrays are ordered the same you can access the second object using
// the index passed from map.
const output = arr.map((o, i) => ({
name: o.name,
image: o.images[0],
price: lineItems[i].amount_total}
));
console.log(output);
// if the two arrays are not in the same order you can use find() to retrieve
// the second object by property (you'll need to check
const outputUsingFind = arr.map(o => {
const lineItem = lineItems.find(item => item.description === o.name);
// ** add lineItem valid check here **
return {
name: o.name,
image: o.images[0],
price: lineItem.amount_total};
});
console.log(outputUsingFind);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to sum values of an array with products and values and order from ascending?

I'm beginner in JavaScript and I'm rendering a list that contains some products.
A product contains several sizes and each size has its price:
const data = [
{
id: "5286",
name: "Alyssa Ashley White Musk",
description: "Sensual but not overpowering",
categories: ["Fresh"],
sizes: [
{
name: "Sample",
price: 0,
},
{
name: "Normal",
price: 4000,
},
{
name: "Large",
price: 6500,
},
],
},
{
id: "6298",
name: "Euphoria",
description:
"Euphoria by Calvin Klein is a woody, oriental scent has notes of pomegranate, black violet, black orchid, and mahogany.",
categories: ["Floriental"],
sizes: [
{
name: "Normal",
price: 7100,
},
],
},
{
id: "9201",
name: "Emporio Armani",
description:
"Emporio Armani by Giorgio Armani bottles style and sophistication for women all over the world to enjoy.",
categories: ["Floriental"],
sizes: [
{
name: "Sample",
price: 0,
},
{
name: "Normal",
price: 2700,
},
],
},
];
export default data;
What I would like is, for example, sum all sizes of product 1 to get the total value. Sum all sizes of product 2 and getting the total value and so on. After obtaining the sum of all products. Sort the list in ascending ones.
I tried using the reducer function. But as inside each product it contains an array with the respective sizes and prices. I didn't know how to do it.
I put my code into codesandbox
Thank you in advance
It will be good to add totalSize key (which contains the sum of item sizes) on each item using Array.map and sort that using Array.sort.
const data = [
{
id: "5286",
name: "Alyssa Ashley White Musk",
description: "Sensual but not overpowering",
categories: ["Fresh"],
sizes: [
{
name: "Sample",
price: 0,
},
{
name: "Normal",
price: 4000,
},
{
name: "Large",
price: 6500,
},
],
},
{
id: "6298",
name: "Euphoria",
description:
"Euphoria by Calvin Klein is a woody, oriental scent has notes of pomegranate, black violet, black orchid, and mahogany.",
categories: ["Floriental"],
sizes: [
{
name: "Normal",
price: 7100,
},
],
},
{
id: "9201",
name: "Emporio Armani",
description:
"Emporio Armani by Giorgio Armani bottles style and sophistication for women all over the world to enjoy.",
categories: ["Floriental"],
sizes: [
{
name: "Sample",
price: 0,
},
{
name: "Normal",
price: 2700,
},
],
},
];
const result = data.map((item) => ({
...item,
totalSize: item.sizes.reduce((sum, cur) => (sum + cur.price), 0)
})).sort((a, b) => a.totalSize - b.totalSize);
console.log(result);

Sorting array of objects by price (lowest to highest)

Below is some of the data that I'm currently working with while making a web app in React.js, right now I'm trying to sort the array of objects by price lowest to highest so that when a button is clicked the array is sorted and is displayed on the DOM from lowest to highest.
A couple of things I'm having to consider is that the prices are all comprised as strings with a '$' character as the first character (EX: '$18') and the second object in the arrays price is "Suggested Donation".
studios: [
{
name: "Whole Yoga",
price: "$17.00"
},
{
name: "Rino Yoga Social",
price: "Suggested Donation"
},
{
name: "Samadhi Yoga",
price: "$20.00"
},
{
name: "Corepower Yoga",
price: "$25.00"
},
{
name: "The River Yoga",
price: "$20.00"
},
{
name: "Endorphin Yoga",
price: "$10.00"
},
{
name: "Kindness Yoga",
price: "$20.00"
},
{
name: "Yoga High",
price: "$15.00"
},
{
name: "Freyja Project",
price: "$22.00"
},
{
name: "Kula Yoga",
price: "$17.00"
}
]
So far I used a while loop to remove the '$' character at the beginning of the string then used .replace() method to replace "Suggested Donation" with '00.00' and parseInt all the prices.
The issue I'm having now is that the new array of sorted prices have nothing to do with the original data (nothing linking them) so I'm just returning an array of sorted prices that I cant do anything with. Anyone have any ideas on how I should go about this?
priceFilter = () => {
let newArr = []
return this.props.studios.filter( studio => {
let price = studio.price;
while(price.charAt(0) === '$') {
price = price.substr(1);
}
price = price.replace('Suggested Donation', '00.00')
let parsedPrice = parseInt(price);
newArr.push(parsedPrice)
return newArr.sort((a,b) => (a - b));
})
}
Convert your values to numbers. Based on your code your suggest price should be 0, so we use that if the price does not start with a dollar sign '$'
const studios = [
{
name: "Whole Yoga",
price: "$17.00"
},
{
name: "Rino Yoga Social",
price: "Suggested Donation"
},
{
name: "Samadhi Yoga",
price: "$20.00"
},
{
name: "Corepower Yoga",
price: "$25.00"
},
{
name: "The River Yoga",
price: "$20.00"
},
{
name: "Endorphin Yoga",
price: "$10.00"
},
{
name: "Kindness Yoga",
price: "$20.00"
},
{
name: "Yoga High",
price: "$15.00"
},
{
name: "Freyja Project",
price: "$22.00"
},
{
name: "Kula Yoga",
price: "$17.00"
}
]
priceFilter = (vals) => {
return vals.sort((a,b) => {
const aPrice = a.price[0] === '$' ? parseFloat(a.price.slice(1,-1)) : 0;
const bPrice = b.price[0] === '$' ? parseFloat(b.price.slice(1,-1)) : 0;
return aPrice - bPrice;
});
}
console.log(priceFilter(studios));
You can write a custom sort with Array.prototype.sort (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort).
const compare = (a, b) => {
const aPrice = Number(a.price.replace(/[^0-9.-]+/g,""));
const bPrice = Number(b.price.replace(/[^0-9.-]+/g,""));
return aPrice - bPrice
};
const sortedStudios = this.props.studios.sort(compare);
You could take a function for getting the value for sorting and then take the delta as redsult for the sorting method.
const getValue = ({ price }) => +price.slice(1) || 0;
var studios = [{ name: "Whole Yoga", price: "$17.00" }, { name: "Rino Yoga Social", price: "Suggested Donation" }, { name: "Samadhi Yoga", price: "$20.00" }, { name: "Corepower Yoga", price: "$25.00" }, { name: "The River Yoga", price: "$20.00" }, { name: "Endorphin Yoga", price: "$10.00" }, { name: "Kindness Yoga", price: "$20.00" }, { name: "Yoga High", price: "$15.00" }, { name: "Freyja Project", price: "$22.00" }, { name: "Kula Yoga", price: "$17.00" }];
studios.sort((a, b) => getValue(a) - getValue(b));
console.log(studios);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Here you go. :)
let studios = [{
name: "Whole Yoga",
price: "$17.00"
},
{
name: "Rino Yoga Social",
price: "Suggested Donation"
},
{
name: "Samadhi Yoga",
price: "$20.00"
},
{
name: "Corepower Yoga",
price: "$25.00"
},
{
name: "The River Yoga",
price: "$20.00"
},
{
name: "Endorphin Yoga",
price: "$10.00"
},
{
name: "Kindness Yoga",
price: "$20.00"
},
{
name: "Yoga High",
price: "$15.00"
},
{
name: "Freyja Project",
price: "$22.00"
},
{
name: "Kula Yoga",
price: "$17.00"
}
];
console.log("Unsorted", studios);
studios.sort(({
price: a
}, {
price: b
}) => {
//parseFloat will be Nan if it cannot parse the string into a number
//the only problem here is that any non int string will turn into 0
a = parseFloat(a.slice(1), 10) || 0;
b = parseFloat(b.slice(1), 10) || 0;
return a - b;
});
console.log("Sorted", studios);
You probably want to sort objects by price instead of sorting prices:
const studios = [{"name":"Whole Yoga","price":"$17.00"},{"name":"Rino Yoga Social","price":"Suggested Donation"},{"name":"Samadhi Yoga","price":"$20.00"},{"name":"Corepower Yoga","price":"$25.00"},{"name":"The River Yoga","price":"$20.00"},{"name":"Endorphin Yoga","price":"$10.00"},{"name":"Kindness Yoga","price":"$20.00"},{"name":"Yoga High","price":"$15.00"},{"name":"Freyja Project","price":"$22.00"},{"name":"Kula Yoga","price":"$17.00"}];
const parsePrice = x => parseFloat(x.replace(/^\$/, '')) || 0
const sortedStudios = studios
.slice()
.sort((a, b) => parsePrice(a.price) - parsePrice(b.price))
console.log(sortedStudios)
Thanks for the help everyone! This solution worked for me.
priceFilter = () => {
let ordered = studios.sort((a, b) => (a.price > b.price) ? 1 : -1);
let lastElement = ordered.pop();
return ordered.unshift(lastElement);
}

Group and merge in nested object using Lodash

I have an object data as follows:
[
{
name: "Green Tea Brownie",
price: 60,
amount: 10,
seller: {
seller_id: 124,
seller_name: "Merry Shop"
}
},
{
name: "Cocoa Chiffon",
price: 20,
amount: 50,
seller: {
seller_id: 124,
seller_name: "Merry Shop"
}
},
{
name: "Milky Donut",
price: 40,
amount: 100
seller: {
seller_id: 421,
seller_name: "Sweet Bakery"
}
}
]
So I want to group data by "seller_id" and merge top level data assigns to object name "orders", just look like as following:
[
{
seller_id: 124,
seller_name: "Merry Shop",
orders: [
{
name: "Green Tea Brownie",
price: 60,
amount: 10
},
{
name: "Cocoa Chiffon",
price: 20,
amount: 50
}
]
},
{
seller_id: 421,
seller_name: "Sweet Bakery",
orders: [
{
name: "Milky Donut",
price: 40,
amount: 100
}
]
}
]
I tried to solve this problem several hours ago. Can anyone solve this case?
Thank you
You can use _.groupBy() and then _.map() the groups to requested format:
const { flow, partialRight: pr, groupBy, map, first, omit } = _
const fn = flow(
pr(groupBy, 'seller.seller_id'),
pr(map, group => ({
...first(group).seller,
orders: map(group, pr(omit, 'seller'))
}))
)
const data = [{"name":"Green Tea Brownie","price":60,"amount":10,"seller":{"seller_id":124,"seller_name":"Merry Shop"}},{"name":"Cocoa Chiffon","price":20,"amount":50,"seller":{"seller_id":124,"seller_name":"Merry Shop"}},{"name":"Milky Donut","price":40,"amount":100,"seller":{"seller_id":421,"seller_name":"Sweet Bakery"}}]
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
If you like to do with plain JS you can use reduce
const data = [{"name":"Green Tea Brownie","price":60,"amount":10,"seller":{"seller_id":124,"seller_name":"Merry Shop"}},{"name":"Cocoa Chiffon","price":20,"amount":50,"seller":{"seller_id":124,"seller_name":"Merry Shop"}},{"name":"Milky Donut","price":40,"amount":100,"seller":{"seller_id":421,"seller_name":"Sweet Bakery"}}]
const output = data.reduce((op,{name,price,amount,seller})=>{
if(op[seller['seller_id']]){
op[seller['seller_id']]['orders'].push({name,price,amount})
}
else {
op[seller['seller_id']] = {
seller_name: seller.seller_name,
seller_id: seller.seller_id,
orders: [{name,price,amount}]
}
}
return op;
},{})
console.log(Object.values(output))
Here is a pure JS solution using reduce:
const orders = [{
name: "Green Tea Brownie",
price: 60,
amount: 10,
seller: {
seller_id: 124,
seller_name: "Merry Shop"
}
}, {
name: "Cocoa Chiffon",
price: 20,
amount: 50,
seller: {
seller_id: 124,
seller_name: "Merry Shop"
}
}, {
name: "Milky Donut",
price: 40,
amount: 100,
seller: {
seller_id: 421,
seller_name: "Sweet Bakery"
}
}];
const ordersBySeller = Object.values(orders.reduce((accum, { name, price, amount, seller: { seller_id, seller_name } }) => {
const sellerOrders = accum[seller_id] ? accum[seller_id].orders || [] : [];
accum[seller_id] = { seller_id, seller_name, orders: [...sellerOrders, { name, price, amount } ] };
return accum;
}, {}));
console.log(ordersBySeller);

Categories

Resources