Delimited List from Nested JavaScript Array - javascript

I have a simple JavaScript object that contains nested arrays.
All I'm looking for here us to return a comma delimited list of the "productID' values that are present at "digitalData.transaction.item.productInfo[i].productID[j]"
I appreciate the help.
Here's an example of the JS (sorry for the length, but better dafe than sorry I guess):
window.digitalData = {
transaction: {
purchaseID: "30010819", //Typically the same as transactionID
transactionID: "30010819", //Unique Identifier for this transaction
item: [{ //Array of items in this transaction
productInfo: {
productID: "63493",
color: "Fuscia", //color if this product has colors
size: "M (8-10)", //size if this product has sizes
sku: "63493-12456", //sku
inventoryStatus: "In Stock", // Mirror the on-site messaging
skuAttr: [{ // extensible array of sku attributes and values
typeLabel: "Color",
valueCode: "FSA",
valueLabel: "Fuscia"
}, {
typeLabel: "Size",
valueLabel: "M (8-10)"
}]
},
price: {
currency: "USD"
},
quantity: 1
}, {
productInfo: {
productID: "55027",
color: "", //color if this product has colors
size: "", //size if this product has sizes
sku: "55027", //sku if known. otherwise use productID
inventoryStatus: "Low Stock", // Mirror the on-site messaging
skuAttr: [] //Empty array if no sku attributes exist
},
price: {
currency: "USD"
},
quantity: 2
}]
}]
}

You can do it that way:
digitalData.transaction.item.map(x => x.productInfo.productID).join(',')

Related

How do I incorporate the index of an array while defining a property of said array within a class in JavaScript?

Sorry if the title makes no sense.. let me explain
Say I have the following 2d array.. the first array representing ice cream and the second representing milkshakes
menu = [ ['vanilla', 'chocolate', 'almond'],
['vanilla', 'pineapple', 'strawberry'] ]
Now I create a class that takes this array as input
class cafe{
constructor(menu){
this.iceCreams = menu[0]
this.milkshakes = menu[1]
}
}
Now I want to define a property called 'price' for each flavor of milkshake.
this.milkshakes[n].price = < a function that computes price based on value of n >
so that i can access them like this :
cafe.milkshakes[0].price
So how do I incorporate the index 'n' of the array while defining the property
I haven't tried anything bcos I dont know how to even approach this ☹️
You can do it in your constructor.
You can grab the names, and call map function on it and do whatever you want. Please check the following example. There, calculatePrice is a function that takes the index and returns the price based on the index.
class Cafe {
constructor (menu) {
this.iceCreams = menu[0].map((flavor, index) => {
return {
flavor,
price: calculatePrice(index)
}
});
this.milkshakes = menu[1].map((flavor, index) => {
return {
flavor,
price: calculatePrice(index)
}
});
}
This is a minimal answer.
UPDATE:
For a detailed and improved answer: https://codesandbox.io/s/cafe-example-wxp2c4
So, in the milkshakes array you need each item as an object data structure, not a string.
menu = [ ['vanilla', 'chocolate', 'almond'],
[{ flavor: 'vanilla' }, { flavor: 'pineapple' }, { flavor: 'strawberry' }] ]
and then you can loop through and set the price, something like this.
menu.milkshakes.forEach((item, index) => item.price = index))
you can use objects:
menu = [
[
{
name: "vanilla",
price: 200,
},
{
name: "chocolate",
price: 200,
},
{
name: "almond",
price: 200,
},
],
[
{
name: "vanilla",
price: 200,
},
{
name: "pineapple",
price: 200,
},
{
name: "strawberry",
price: 200,
},
],
];
and then:
class cafe{
constructor(menu){
this.iceCreams = menu[0]
this.milkshakes = menu[1]
}
}
now iceCreams and milshakes have the property price and name
example:
iceCreams[n].price
iceCreams[n].name

Workarounds to using this in Vue

I am attempting to create a PayPal checkout order on my Vue site. I am currently passing two props to the component as well as two data objects
props: {
price: Number,
shipping: Number,
},
data() {
return {quantity: 1, switches: 'red'}
},
I am referencing these four variables in my code as this.price, this.shipping etc. I have confirmed these are all valid
I am attempting to access these inside a method but this is being over-ridden and all four of these are undefined.
I still don't quite understand this, but I was under the impression that using an arrow function as I have done should stop this from changing. Is this not the case?
Code
await paypal.Buttons({
style: {
layout: 'vertical',
color: 'black',
shape: 'pill',
},
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [{
amount: {
currency_code: "USD",
value: ((this.price + this.shipping) * this.quantity).toString(),
breakdown: {
item_total: { /* Required when including the `items` array */
currency_code: "USD",
value: this.price.toString()
},
shipping: {
currency_code: "USD",
value: this.shipping.toString()
}
}
},
items: [
{
name: "First Product Name", /* Shows within upper-right dropdown during payment approval */
description: "Optional descriptive text..", /* Item details will also be in the completed paypal.com transaction view */
unit_amount: {
currency_code: "USD",
value: this.price.toString()
},
quantity: this.quantity.toString
},
]
}]
});
},
}).render('#paypal-button-container')

Nested arrays with objects, lodash meanBy

Can someone please help me understand how to make this work. Everytime I feel like I start to understand arrays and objects in Javascript it turns out that I still don't.
I'm trying to get the average of all prices in the following datastructure by using lodash meanBy
[
{
date: "2019-12-17",
items: [
{ id: "1", state: "accepted", price: "90.5" },
{ id: "2", state: "rejected", price: "20.0" },
{ id: "3", state: "open", price: "10.5" },
]
},
{
date: "2019-12-18",
items: [
{ id: "4", state: "open", price: "450.0" },
{ id: "5", state: "rejected", price: "40.1" },
{ id: "6", state: "accepted", price: "50.9" },
]
}
]
If you provide the answer, can you also please try to explain how you select something nested in items, because that's as far as I get before I get lost.
In this case instead of selecting nested values, it's easier to flatten the items to a single array, and then apply _.meanBy(). In addition, the prices are strings, and not numbers, so you'll need to convert them.
Flatten the items to a single array with Array.flatMap(), and then use _.meanBy(), and get the numeric values of the prices:
const data = [{"date":"2019-12-17","items":[{"id":"1","state":"accepted","price":"90.5"},{"id":"2","state":"rejected","price":"20.0"},{"id":"3","state":"open","price":"10.5"}]},{"date":"2019-12-18","items":[{"id":"4","state":"open","price":"450.0"},{"id":"5","state":"rejected","price":"40.1"},{"id":"6","state":"accepted","price":"50.9"}]}]
const result = _.meanBy(_.flatMap(data, 'items'), o => +o.price)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Another approach is to get the general average, by getting the average of each items array separately , and then getting the average of all averages.
const data = [{"date":"2019-12-17","items":[{"id":"1","state":"accepted","price":"90.5"},{"id":"2","state":"rejected","price":"20.0"},{"id":"3","state":"open","price":"10.5"}]},{"date":"2019-12-18","items":[{"id":"4","state":"open","price":"450.0"},{"id":"5","state":"rejected","price":"40.1"},{"id":"6","state":"accepted","price":"50.9"}]}]
const result = _.meanBy(data, ({ items }) => _.meanBy(items, o => +o.price))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

how to search nested objects and group according to a field

I have an array that contains nested objects, and i want to filter the objects according to a particular field. Items array contains an item object, that contains some particular field like name, id, price, and vendorid. I want to sort and filter the array according to the vendorid field. For example an array like :
var items=[{item:{name:"cap",
id:"5d767e1358ad1d0ca4894592",
price:50,
vendorid:"5d72d2a6d87c4628ba60e046"
},
}
{item:{name:"shorts",
price:100,
vendorid:"5d71c51f2092d318a1bf8f53"
}
},
{item:{name:"shoes",
price:90,
vendorid:"5d71c51f2092d318a1bf8f53"
}
}
{item:{name:"black hood",
price:120,
vendorid:"5d71c51f2092d318a1bf8f53"
}
}
]
I want to create an object that outputs this :
results = {"5d71c51f2092d318a1bf8f53":[{name:"shorts"
price:100,
vendorid:"5d71c51f2092d318a1bf8f53"},
{name:"shoes",
price:90,
vendorid:"5d71c51f2092d318a1bf8f53"},
{name:"black hood",
price:120,
vendorid:"5d71c51f2092d318a1bf8f53"}
],
"5d72d2a6d87c4628ba60e046":[{name:"cap",
id:"5d767e1358ad1d0ca4894592",
price:50,
vendorid:"5d72d2a6d87c4628ba60e046"
}
]
}
The results object format is {vendorid:[array containing objects with the same vendorid]}.
Thanks very much!!!
You can use reduce() method to do that.
var items = [{ item: { name: "cap", id: "5d767e1358ad1d0ca4894592", price: 50, vendorid: "5d72d2a6d87c4628ba60e046" } } ,{ item: { name: "shorts", price: 100, vendorid: "5d71c51f2092d318a1bf8f53" } }, { item: { name: "shoes", price: 90, vendorid: "5d71c51f2092d318a1bf8f53" } }, { item: { name: "black hood", price: 120, vendorid: "5d71c51f2092d318a1bf8f53" } } ];
let result = items.reduce((obj, currentValue) => {
if (!obj[currentValue.item.vendorid]) {
obj[currentValue.item.vendorid] = [];
}
obj[currentValue.item.vendorid].push({
...currentValue.item
});
return obj;
}, {});
const orderedResult = {};
// Sorting on vendorid.
Object.keys(result).sort().forEach(key => orderedResult[key] = result[key]);
console.log(orderedResult);
A note on ordering of object properties:
As of ECMAScript 2015 (ES6), object's own properties do have order
for some operations, but relying on it isn't a good idea. If order is
important, then better to use an array or something similar.

How to get highest difference between two numbers in a JSON object

I'm working with NodeJS to create a "Featured Product" widget on a website. I have a JSON object with SKU, price, and sale_price. What's the best way to get the SKU of the item that has the highest discount (Difference between price and sale_price)?
I tried doing it by for looping through the items and find the difference between price and sale_price, push the results to an array then get the max, but I cannot get the SKU at that point.
Example of the JSON object that I have:
{ "item_number":12341231, "price":"250", "sale_price":"219.99"},
{ "item_number":12341232, "price":"210", "sale_price":"209.99"},
{ "item_number":12341233, "price":"20", "sale_price":"12.99"},
{ "item_number":12341234, "price":"150", "sale_price":"19.99"},
{ "item_number":12341235, "price":"60", "sale_price":"29.99"},
{ "item_number":12341236, "price":"10", "sale_price":"5.99"}
];
For example the program would return 1231234 as the SKU of the featured item, because the discount is ~$130.
I just want a quick solution, don't worry about performance.
You could reduce the array with a single loop and take the one with the greatest delta.
var array = [{ item_number: 12341231, price: "250", sale_price: "219.99" }, { item_number: 12341232, price: "210", sale_price: "209.99" }, { item_number: 12341233, price: "20", sale_price: "12.99" }, { item_number: 12341234, price: "150", sale_price: "19.99" }, { item_number: 12341235, price: "60", sale_price: "29.99" }, { item_number: 12341236, price: "10", sale_price: "5.99" }],
result = array.reduce((a, b) =>
a.price - a.sale_price > b.price - b.sale_price ? a : b);
console.log(result);
If performance is not an issue, you can sort your products in descending order and get the first one from the sorted result:
const data = [
{ "item_number":12341231, "price":"250", "sale_price":"219.99"},
{ "item_number":12341232, "price":"210", "sale_price":"209.99"},
{ "item_number":12341233, "price":"20", "sale_price":"12.99"},
{ "item_number":12341234, "price":"150", "sale_price":"19.99"},
{ "item_number":12341235, "price":"60", "sale_price":"29.99"},
{ "item_number":12341236, "price":"10", "sale_price":"5.99"}
];
const maxDiffProduct = data.sort((a, b) => (b.price - b.sale_price) - (a.price - a.sale_price))[0];
console.log(maxDiffProduct.item_number);

Categories

Resources