Related
I would like to get the summed value of all the arrays in the "products" object (price * quantity). The summed value should be returned in the return.
Do you have any ideas how to do that?
{
"event": "checkout",
"ecommerce": {
"checkout": {
"actionField": {
"step": 2,
"option": "Initiate checkout",
"action": "checkout"
},
"products": [
{
"id": "52",
"name": "Turystyczna kuchenka gazowa SMILE-KN-03/1K",
"price": 161.788618,
"brand": "",
"category": "kuchenki-elektryczne-i-gazowe",
"variant": "",
"quantity": "1"
},
{
"id": "36",
"name": "Kuchnia gazowa MPM-51-KGF-21",
"price": 641.463415,
"brand": "",
"category": "kuchnie-gazowe",
"variant": "",
"quantity": "1"
}
]
}
},
"gtm.uniqueEventId": 12
}
const g = {
event: 'checkout',
ecommerce: {
checkout: {
actionField: {
step: 2,
option: 'Initiate checkout',
action: 'checkout',
},
products: [
{
id: '52',
name: 'Turystyczna kuchenka gazowa SMILE-KN-03/1K',
price: 161.788618,
brand: '',
category: 'kuchenki-elektryczne-i-gazowe',
variant: '',
quantity: '1',
},
{
id: '36',
name: 'Kuchnia gazowa MPM-51-KGF-21',
price: 641.463415,
brand: '',
category: 'kuchnie-gazowe',
variant: '',
quantity: '1',
},
],
},
},
'gtm.uniqueEventId': 12,
};
const c = g.ecommerce.checkout.products.reduce((acc, curr) => {
acc += curr.price * curr.quantity;
return acc;
}, 0);
console.log(c)
guess you want something like this?
I have a 2D array where the outer array contains objects, each of which contains another array of objects. Here is the data:
const companies = [{
companyId: 100,
companyName: "Company 1",
transactions: [
{ id: "10421", date: "09/19/2022", selected: true, },
{ id: "00467", date: "05/08/2022", selected: true, },
],
},
{
companyId: 200,
companyName: "Company 2",
transactions: [
{ id: "259A6", date: "01/11/2022", selected: false, },
{ id: "87K37", date: "04/14/2022", selected: false, },
],
},
];
I want to get the list of transactions that have their selected fields set to true. This is how I am filtering the data:
const selectedTransactions = companies.filter((c) =>
c.transactions.filter((t) => t.selected === true));
Instead of getting the transactions of only the first company, I'm getting the transactions of ALL companies, including the ones that are not selected. Am I making a mistake somewhere?
You could flat-map the overall companies; then internally filter and map the transaction IDs and dates along with the company ID.
const companies = [{
companyId: 100,
companyName: "Company 1",
transactions: [
{ id: "10421", date: "09/19/2022", selected: true },
{ id: "00467", date: "05/08/2022", selected: true },
],
}, {
companyId: 200,
companyName: "Company 2",
transactions: [
{ id: "259A6", date: "01/11/2022", selected: false },
{ id: "87K37", date: "04/14/2022", selected: false },
],
}];
const selected = companies
.flatMap(({ companyId, transactions }) => transactions
.filter(({ selected }) => selected)
.map(({ id: transactionId, date: transactionDate }) =>
({ companyId, transactionId, transactionDate })));
console.log(selected);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Result
[
{ "companyId": 100, "transactionId": "10421", "transactionDate": "09/19/2022" },
{ "companyId": 100, "transactionId": "00467", "transactionDate": "05/08/2022" }
]
If youre just looking for the transactions you could use map, though it does return a second empty array. Or just add a little to your filter function to get only the company with what youre looking for.
const companies = [{
companyId: 100,
companyName: "Company 1",
transactions: [
{ id: "10421", date: "09/19/2022", selected: true },
{ id: "00467", date: "05/08/2022", selected: true },
],
}, {
companyId: 200,
companyName: "Company 2",
transactions: [
{ id: "259A6", date: "01/11/2022", selected: false },
{ id: "87K37", date: "04/14/2022", selected: false },
],
}];
// USING MAP TO GET TRANSACTIONS
const st = companies.map(c => c.transactions.filter(t => t.selected === true))
console.log(st);
// USING FILTER TO GET COMPANY
const selectedTransactions = companies.filter(c => {
c.transactions = c.transactions.filter(t => t.selected === true);
if (c.transactions.length) return c;
});
console.log(selectedTransactions);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Result
1
[
[
{
"id": "10421",
"date": "09/19/2022",
"selected": true
},
{
"id": "00467",
"date": "05/08/2022",
"selected": true
}
],
[]
]
2
[
{
"companyId": 100,
"companyName": "Company 1",
"transactions": [
{
"id": "10421",
"date": "09/19/2022",
"selected": true
},
{
"id": "00467",
"date": "05/08/2022",
"selected": true
}
]
}
]
I have an array of objects as below
let arr = [
{
name: "string 1",
details: [
{
id: 1,
values: [
{ date: "12-Mar", score: "15" },
{ date: "13-Mar", score: "16" },
{ date: "14-Mar", score: "17" },
{ date: "15-Mar", score: "18" },
],
},
],
},
{
name: "string 2",
details: [
{
id: 2,
values: [
{ date: "12-Mar", score: "16" },
{ date: "13-Mar", score: "17" },
{ date: "14-Mar", score: "18" },
{ date: "15-Mar", score: "19" },
],
},
],
},
{
name: "string 3",
details: [
{
id: 2,
values: [
{ date: "12-Mar", score: "21" },
{ date: "13-Mar", score: "22" },
{ date: "14-Mar", score: "23" },
{ date: "15-Mar", score: "24" },
],
},
],
},
];
I also have the same data as an object of objects as below
let obj = {
"string 1": {
details: [
{
id: 1,
values: [
{ date: "12-Mar", score: "15" },
{ date: "13-Mar", score: "16" },
{ date: "14-Mar", score: "17" },
{ date: "15-Mar", score: "18" },
],
},
],
},
"string 2": {
details: [
{
id: 2,
values: [
{ date: "12-Mar", score: "16" },
{ date: "13-Mar", score: "17" },
{ date: "14-Mar", score: "18" },
{ date: "15-Mar", score: "19" },
],
},
],
},
"string 3": {
details: [
{
id: "2",
values: [
{ date: "12-Mar", score: "21" },
{ date: "13-Mar", score: "22" },
{ date: "14-Mar", score: "23" },
{ date: "15-Mar", score: "24" },
],
},
],
},
};
I want to find all the dates & all the scores as an array.
For the array of ojects, with the help of answer here (How to find all values of a specific key in an array of nested objects?), I was able to get the result with the code below.
Since I did not want the dates to be repeated, I created a Set
dates = new Set(getValue(arr, "date"))
However, for the object of objects, I am not able to get the results. How do I go about it.
Also, I have the option to get my data as an array of objects or an object of objects. Since I have to perform a lot of manipulation/analysis (I will be using this with D3 library t build charts), which is the better format? Can anyone guide? Thanks.
You could use a recursive approach (as in the referenced answer) to pick all properties for a given key. One can also add a unique parameter, if this is set to true we'll create a Set from the properties to ensure we don't return any duplicates:
let arr = [ { name: "string 1", details: [ { id: 1, values: [ { date: "12-Mar", score: "15" }, { date: "13-Mar", score: "16" }, { date: "14-Mar", score: "17" }, { date: "15-Mar", score: "18" }, ], }, ], }, { name: "string 2", details: [ { id: 2, values: [ { date: "12-Mar", score: "16" }, { date: "13-Mar", score: "17" }, { date: "14-Mar", score: "18" }, { date: "15-Mar", score: "19" }, ], }, ], }, { name: "string 3", details: [ { id: 2, values: [ { date: "12-Mar", score: "21" }, { date: "13-Mar", score: "22" }, { date: "14-Mar", score: "23" }, { date: "15-Mar", score: "24" }, ], }, ], }, ];
let obj = { "string 1": { details: [ { id: 1, values: [ { date: "12-Mar", score: "15" }, { date: "13-Mar", score: "16" }, { date: "14-Mar", score: "17" }, { date: "15-Mar", score: "18" }, ], }, ], }, "string 2": { details: [ { id: 2, values: [ { date: "12-Mar", score: "16" }, { date: "13-Mar", score: "17" }, { date: "14-Mar", score: "18" }, { date: "15-Mar", score: "19" }, ], }, ], }, "string 3": { details: [ { id: "2", values: [ { date: "12-Mar", score: "21" }, { date: "13-Mar", score: "22" }, { date: "14-Mar", score: "23" }, { date: "15-Mar", score: "24" }, ], }, ], }, };
function getProperties(obj, key, unique = true, result = []) {
for(let k in obj) {
if (typeof(obj[k]) === 'object') {
getProperties(obj[k], key, unique, result);
} else if (k === key) {
result.push(obj[k]);
}
}
return unique ? [...new Set(result)]: result;
}
console.log('Dates (arr):', JSON.stringify(getProperties(arr, 'date', true)))
console.log('Scores (arr):', JSON.stringify(getProperties(arr, 'score', true)))
console.log('Dates (obj):', JSON.stringify(getProperties(obj, 'date', true)))
console.log('Scores (obj):', JSON.stringify(getProperties(obj, 'score', true)))
You can iterate over the top-level keys in your object like this:
for (let key in obj){
let val = obj[key]
/* From here you can proceed with finding all values
like you did with the array
*/
}
I have the following object:
[
{ createdAt: "08-08-2020, 12:04:19 am", id: "1" },
{ createdAt: "08-08-2020, 12:04:19 am", id: "2" },
{ createdAt: "08-10-2020, 12:04:19 am", id: "3" },
{ createdAt: "08-10-2020, 12:04:19 am", id: "4" },
{ createdAt: "08-12-2020, 12:04:19 am", id: "5" },
{ createdAt: "08-20-2020, 12:04:19 am", id: "6" }
]
As you can see, every array has a creation date and an specific value. What I wanna do here is to create a new object that looks like this:
[
{ createdAt: "08-08-2020", ids: ["1", "2"] },
{ createdAt: "08-10-2020", ids: ["3", "4"] },
{ createdAt: "08-12-2020", ids: ["5"] },
{ createdAt: "08-20-2020", ids: ["6" ]}
]
Basically arranging the ids by date of creation. I've been trying to filter and map this with ECMA6 but the logic it's just not clear to me.
Any help would be greatly appreciated.
Thanks in advance!
First, create a map between the createdAt and the ids
const array = [
{ createdAt: "08-08-2020, 12:04:19 am", id: "1" },
{ createdAt: "08-08-2020, 12:04:19 am", id: "2" },
{ createdAt: "08-10-2020, 12:04:19 am", id: "3" },
{ createdAt: "08-10-2020, 12:04:19 am", id: "4" },
{ createdAt: "08-12-2020, 12:04:19 am", id: "5" },
{ createdAt: "08-20-2020, 12:04:19 am", id: "6" }
]
const map = {}
array.forEach(item => {
if (map[item.createdAt] === undefined) {
map[item.createdAt] = []
}
map[item.createdAt].push(item.id)
})
Then, rearrange the map into an array:
const resultingArray = Object.entries(map).map(([createdAt, ids]) => ({
createdAt,
ids
}))
This can be accomplished with a basic reduce operation, grouping elements with the same date using an object.
const arr = [
{ createdAt: "08-08-2020, 12:04:19 am", id: "1" },
{ createdAt: "08-08-2020, 12:04:19 am", id: "2" },
{ createdAt: "08-10-2020, 12:04:19 am", id: "3" },
{ createdAt: "08-10-2020, 12:04:19 am", id: "4" },
{ createdAt: "08-12-2020, 12:04:19 am", id: "5" },
{ createdAt: "08-20-2020, 12:04:19 am", id: "6" }
];
const res = Object.values(
arr.reduce((acc,{createdAt, id})=>{
const date = createdAt.split(",")[0];
acc[date] = acc[date] || {createdAt: date, ids: []};
acc[date].ids.push(id);
return acc;
}, {})
);
console.log(res);
var timeslots = [
{
"details": [{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/16"
},
{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/26"
}],
"time": "10:30 AM",
"status": "Booked"
},
{
"details": [{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/26"
},{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/26"
}],
"time": "11:30 AM",
"status": "Booked"
},
{
"details": [{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/16"
},{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/23"
}],
"time": "12:30 PM",
"status": "Booked"
},
{
"details": [{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/16"
},{
"name":"naveen",
"email":"navee#gmail.com",
"date":"2019/12/16"
}],
"time": "02:30 PM",
"status": "Booked"
},
{
"details": [{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/16"
},{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/16"
}],
"time": "03:30 PM",
"status": "Booked"
},
{
"details": [{
"name":"naveen",
"email":"naveeni#gmail.com",
"date":"2019/12/16"
},{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/16"
}],
"time": "04:30 PM",
"status": "Booked"
},
{
"details": [{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/16"
},{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/16"
}],
"time": "05:30 PM",
"status": "Booked"
}
]
I have time slots like 09:00 am --09:00 pm, based on today's date I need to iterate the list of objects and i need to remove the previous date object respectively in nodejs, javascript
SO please help me with this
Expected output
var date ="23/12/2019"
var timeslots = [
{
"details": [
{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/26"
}],
"time": "10:30 AM",
"status": "Booked"
},
{
"details": [{
"name":"naveen",
"email":"naveeni#gmail.com",
"date":"2019/12/26"
},{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/26"
}],
"time": "11:30 AM",
"status": "Booked"
},
{
"details": [{
"name":"naveen",
"email":"naveen#gmail.com",
"date":"2019/12/23"
}],
"time": "12:30 PM",
"status": "Booked"
},
{
"details": [],
"time": "02:30 PM",
"status": "Booked"
},
{
"details": [],
"time": "03:30 PM",
"status": "Booked"
},
{
"details": [],
"time": "04:30 PM",
"status": "Booked"
},
{
"details": [],
"time": "05:30 PM",
"status": "Booked"
}
]
how can I iterate this
I have time slots like 09:00 am --09:00 pm, based on today's date I need to iterate the list of objects and I need to remove the previous date object respectively in nodejs, javascript
SO please help me with this
From comments below
timeslots.time.forEach(function(value) {
console.log(value.time);
value.details.forEach(function(model) {
console.log(value.details);
value.date.forEach(function(date) {
console.log(value.date)
})
});
});
for (var i = 0; i < timeslots.length; i++) {
if (timeslots[i].details[i].date < today) {
list.push(timeslots[i].details[i].date)
}
}
slots.reduceRight(function(acc, obj, idx) {
if (list.indexOf(obj.date) > -1) slots.splice(idx, 1);
}, 0);
I looked through your code and there are a couple of things that are incorrect and that can be improved.
var date ="23/12/2019" // string needs to be "2019/12/23" to be parsed by 'Date'
for (var i = 0; i < timeslots.length; i++) { // can be replaced with map
if (timeslots[i].details[i].date < today) { // this is comparing strings, not dates
list.push(timeslots[i].details[i].date) // can be replaced by filter on details
}
}
I've converted your code using the things I've seen:
const today = "2019/12/23";
const timeslots = [...]
const answer = timeslots.map(timeSlot => {
return {
...timeSlot, // this is called the spread operator
details: timeSlot.details.filter(detail => {
return new Date(detail.date).getTime() >= new Date(today).getTime()
})
}
})
We map the timeslots to a new object, copying the existing proerties across using the spread operator.
We then override the details property, by having it beneath in the object declaration, with a filtered version of the array.
We are filtering based on the getTime result of the parsed date strings. getTime returns the epoch timestamp of the Date object. This makes our comparison easier because they are just numbers.
If I understand correctly, you can think about your problem as such: (1) You want to remove all details that are older than a specific date and (2) then you want to remove all timeslots that don't have any details left.
Consider using object-scan. It's powerful for data processing once you wrap your head around it. Here is how you could solve your issue with it:
// const objectScan = require('object-scan');
const prune = (date, input) => {
const jsDate = new Date(date);
const logic = {
'[*].details': (value) => value.length === 0,
'[*].details[*].date': (value) => jsDate > new Date(value)
};
return objectScan(Object.keys(logic), {
rtn: 'bool',
filterFn: ({ matchedBy, value, gparent, gproperty }) => {
if (matchedBy.some((n) => logic[n](value))) {
gparent.splice(gproperty, 1);
return true;
}
return false;
}
})(input);
};
const timeslots = [ { details: [ { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/16' }, { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/26' } ], time: '10:30 AM', status: 'Booked' }, { details: [ { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/26' }, { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/26' } ], time: '11:30 AM', status: 'Booked' }, { details: [ { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/16' }, { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/23' } ], time: '12:30 PM', status: 'Booked' }, { details: [ { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/16' }, { name: 'naveen', email: 'navee#gmail.com', date: '2019/12/16' } ], time: '02:30 PM', status: 'Booked' }, { details: [ { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/16' }, { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/16' } ], time: '03:30 PM', status: 'Booked' }, { details: [ { name: 'naveen', email: 'naveeni#gmail.com', date: '2019/12/16' }, { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/16' } ], time: '04:30 PM', status: 'Booked' }, { details: [ { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/16' }, { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/16' } ], time: '05:30 PM', status: 'Booked' } ];
console.log(prune('2019/12/23', timeslots)); // return true iff changes made
// => true
console.log(timeslots);
// => [ { details: [ { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/26' } ], time: '10:30 AM', status: 'Booked' }, { details: [ { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/26' }, { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/26' } ], time: '11:30 AM', status: 'Booked' }, { details: [ { name: 'naveen', email: 'naveen#gmail.com', date: '2019/12/23' } ], time: '12:30 PM', status: 'Booked' } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan#16.0.0"></script>
Disclaimer: I'm the author of object-scan