JavaScript add row level total property - javascript

I have the following javascript array:
[{ Year:2000, Jan:1, Feb: }, {Year:2001, Jan:-1, Feb:0.34 }]
I would like to add the total of Jan and Feb as a new property in the existing array.
Example:
[{ Year:2000, Jan:1, Feb:, Total: 1 }, {Year:2001, Jan:2, Feb:4, Total: -0.66 }]
How can I do this using JavaScript?
EDIT: Updated with decimal values

Assuming the empty value in Feb means 0 the following code will work.
var data = [{ Year:2000, Jan:1, Feb:0 }, {Year:2001, Jan:2, Feb:4 }];
data.forEach(item => {
item.Total = item.Jan + item.Feb;
});
console.log(data); /* [
{ Year: 2000, Jan: 1, Feb: 0, Total: 1 },
{ Year: 2001, Jan: 2, Feb: 4, Total: 6 }
]*/

Given:
const myArray = [{ Year:2000, Jan:1, Feb: 2}, {Year:2001, Jan:2, Feb:4 }];
Just iterate over the months.
myArray.forEach(y => y.Total = y.Jan + y.Feb)
You can add more months to it
myArray.forEach(y => y.Total = y.Jan + y.Feb + y.Mar + y.Apr)

Suppose data to have the array.
const data = [{ Year:2000, Jan:1, Feb: }, {Year:2001, Jan:2, Feb:4 }]
You can use Array.forEach to change the existing array.
data.forEach((item) => {
const total = (item.Jan || 0) + (item.Feb || 0);
item.Total = total;
});
here (item.Jan || 0) would ensure 0 for an undefined Jan

Related

How to combine 2 or more API sources into one table (React, HTML)

So I have 3 API sources that return data in this format
firstSource = [{month, endDate, expectedPrice}] ->array of 12 objects
secondSource = [{month, value}] ->array of 12 objects
thirdSource = [{month, value}] ->array of 12 objects
example:
secondSource = [
{month: 1, value: 234.22},
{month: 2, value: 123.58},
{month: 3, value: 255.35},
...
...
you get the idea
]
I've come across this solution that uses lodash library. This is all well, but I'm interested in a solution that doesn't require external libraries. So basically, I want to achieve the same thing the person from the lodash solution did -> combine all three data sources into one and then use that to display the data in <table> element, only without using external libraries, e.g. lodash.
Expected output:
combined = [
{month, endDate, expectedPrice, secondSourceValue, thirdSourceValue}
]
Any ideas?
what's the problem to try something like this?
let combinedData = []
firstSource.forEach((element, index) => {
combinedData[index] = {
month: element.month,
endDate: element.endDate,
expectedPrice: element.expectedPrice,
secondSourceValue: secondSource[index].value,
thirdSourceValue: thirdSource[index].value
}
});
You only have to check if the second and third sources have the same length with the main.
We can use array.mapto merge multiple arrays of objects and create a new array with properties of all objects.
Do note that, in this case, the length of all the arrays should be the same.
let arr1 = [{
month: 1,
value: 234.22,
date: 'JAN'
},
{
month: 2,
value: 123.58,
date: 'FEB'
},
{
month: 3,
value: 255.35,
date: 'MARCH'
}
]
let arr2 = [{
month: 1,
property: 1
},
{
month: 2,
property: 2
},
{
month: 3,
property: 3
}
]
let arr3 = [{
month: 1,
property: 9
},
{
month: 2,
property: 8
},
{
month: 3,
property: 7
},
]
let combinedArr = arr1.map((item, index) => {
return {
...item,
...arr2[index],
...arr3[index]
}
})
console.log(combinedArr)

Merging nested array by object's ID [duplicate]

This question already has answers here:
How can I group an array of objects by key?
(32 answers)
Merge JavaScript objects in array with same key
(15 answers)
Closed 7 months ago.
I have an array of objects each with a nested array and a non-unique ID. I would like to concatenate the objects subarrays where the ID's match.
With the following input:
inputArr = [
{id: 1,
days: ["2022-09-05",
"2022-09-06",
]
},
{id: 2,
days: ["2022-10-05",
"2022-10-06"]
},
{id: 1,
days: ["2022-09-05",
"2022-09-06",
"2022-09-07",
"2022-09-08"]
},
{id: 2,
days: ["2022-10-05",
"2022-10-08"]
},
]
My desired output is as follows:
outputArr = [
{id: 1,
days: ["2022-09-05",
"2022-09-06",
"2022-09-07",
"2022-09-08"
]
},
{id: 2,
days: ["2022-10-05",
"2022-10-06",
"2022-10-08"]
},
]
Ideally I would like to do this without the use of for loops and instead use a map, filter, reduce strategy. I have tried a couple of variations but am having trouble with the nesting. Thanks in advance for the help! Its greatly appreciated.
Not an elegant solution but something like this could work:
let inputArr = [
{ id: 1, days: ["2022-09-05", "2022-09-06"] },
{ id: 2, days: ["2022-10-05", "2022-10-06"] },
{ id: 1, days: ["2022-09-05", "2022-09-06", "2022-09-07", "2022-09-08"] },
{ id: 2, days: ["2022-10-05", "2022-10-08"] },
];
let outputObj = {};
inputArr.forEach(
(item) =>
(outputObj[item.id] = outputObj[item.id]
? [...outputObj[item.id], ...item.days]
: item.days)
);
let outputArr = Object.entries(outputObj).map((item) => ({
id: parseInt(item[0]),
days: Array.from(new Set(item[1])),
}));
Output:
[
{
id: 1,
days: [ '2022-09-05', '2022-09-06', '2022-09-07', '2022-09-08' ]
},
{ id: 2, days: [ '2022-10-05', '2022-10-06', '2022-10-08' ] }
]
My approach using reduce
const inputArr = [
{ id: 1, days: ["2022-09-05", "2022-09-06"] },
{ id: 2, days: ["2022-10-05", "2022-10-06"] },
{ id: 1, days: ["2022-09-05", "2022-09-06", "2022-09-07", "2022-09-08"] },
{ id: 2, days: ["2022-10-05", "2022-10-08"] },
];
const outputArr = inputArr.reduce((accArr, currObj) => {
let ind = accArr.findIndex((obj) => obj.id == currObj.id);
if (ind < 0) {
accArr.push({ ...currObj, days: [...new Set(currObj.days)].slice().sort() });
} else {
accArr[ind].days = [...new Set([...accArr[ind].days, ...currObj.days])].slice().sort();
}
return accArr;
}, []);
console.log(JSON.stringify(outputArr, null, 4));
Result
[
{
"id": 1,
"days": [
"2022-09-05",
"2022-09-06",
"2022-09-07",
"2022-09-08"
]
},
{
"id": 2,
"days": [
"2022-10-05",
"2022-10-06",
"2022-10-08"
]
}
]
Note: [...new Set(array)] to get only unique values from that array.

Group array of objects by multiple properties with Lodash

is possible with lodash library group elements by 2 properties?
I have array of objects like this:
[{
id: 1,
amount: 2000,
date: "2018-01-31T00:00:00.000Z"
},{
id: 2,
amount: 3000,
date: "2017-07-31T00:00:00.000Z"
},{
id: 3,
amount: 6000,
date: "2018-01-31T00:00:00.000Z"
},{
id: 4,
amount: 7000,
date: "2017-01-31T00:00:00.000Z"
},{
id: 5,
amount: 5000,
date: "2017-03-31T00:00:00.000Z"
},{
id: 6,
amount: 3000,
date: "2018-02-22T00:00:00.000Z"
},{
id: 7,
amount: 4500,
date: "2017-01-31T00:00:00.000Z"
}]
My goal is group objects in array by:
year
month
Purpose of that grouping is that I need in result order these objects' sum of amount by newest. So for that reason I need distinguish January 2017 from January 2018. It should be 2 different groups.
I am not sure if my approach is correct so I write here my required output:
[
3000, // sum of 2018-2
8000, // sum of 2018-1
3000 // sum of 2017-7
5000 // sum of 2017-3
11500 // sum of 2017-1
]
I tried following command but it doesn't work and give me error:
let xxx = _(data)
.groupBy(function(i) {
new Date(i.date).getFullYear()
})
.groupBy(function(i) {
new Date(i.date).getMonth()
})
.map(x => x.amount)
.sum()
.orderBy('date').value();
Can you help me to fix it ? Thanks.
You can just concat your year and month with groupBy and use it.
var grouped = _.groupBy(data, function(i) {
return new Date(i.date).getFullYear()+'-'+new Date(i.date).getMonth()
})
var resultUnsorted = _.map(t, (val, key) => ({key: key, val: val.reduce((p, c) => c.amount + p, 0) }));
then sort using _.orderBy
const output = _.orderBy(resultUnsorted, 'key');
you can write your custom sort function using the behaviour you want.

Retrieve a flattened array of values taken from an object array that exists within a top-level object of which I am given an array

Please feel free to modify title, it was rather hard for me to explain and thus search.
var booking = [
{
x: "1",
y: "2",
days: [
{
hours: 8
},
]
},
{...}
]
var hoursBooked = [8, 2, 4, 8, 2, 8, 3, 4]; // this is what I want
So I have an array of 'Booking' objects.
Each Booking can have a number of days in an array of 'Day' objects.
In the 'Day' object lies an 'Hours' property.
All I want to do - is loop through the bookings array and output a flattened array of 'Hours' values (so I can visualise in a graph).
I am sure there's a nice functional or otherwise clean approach to doing this rather than using a sequence of 'for' loops.
Anyone?
Lodash 4x
var booking = [
{
x: "1",
y: "2",
days: [
{
hours: 8
},
]
},
{
x: "1",
y: "2",
days: [
{
hours: 3
},
{
hours: 5
}
]
}
];
_(booking).map('days').flatten().map('hours').value();
Will print
[8, 3, 5]
You could reduce booking with the values of the days arrays.
var booking = [{ x: "1", y: "2", days: [{ hours: 8 }, { hours: 4 }, ] }, { x: "3", y: "4", days: [{ hours: 1 }, { hours: 3 }, ] }, { x: "3", y: "4", days: [] }],
hoursBooked = booking.reduce((r, a) => r.concat((a.days || []).map(d => d.hours)), []);
console.log(hoursBooked);
var booking = [
{
x: "1",
y: "2",
days: [
{
hours: 8
},
{
hours: 2
}
]
},
{
x: "1",
y: "2",
days: [
{
hours: 4
},
]
}
]
var hoursBooked = []
booking.forEach(b=>b.days.forEach(d=>hoursBooked.push(d.hours)))
console.log(hoursBooked)

How can i put loop and get values in javascript?

<script>
var data={
Data: {
name: 'aaaa',
number: '0003'
},
values: {
val: '-20.00',
rate: '22047'
},
user: [ '6|1|5', '10|1|15' ]
};
console.log(data);
console.log(data.user.length);
for(var i=0;i<data.user.length;i++) {
console.log(data.user[i]);
}
</script>
Above is my code i want to put loop and get values like this
this is my data user: [ '6|1|5', '10|1|15' ]
but i want to get like this:
userid - 6
roolno - 1
rank - 5
userid - 10
roolno - 1
rank - 15
how can i do this any one help me out ?
A simple map would do it (see plunker):
data.user.map(function(x) {
var parts = x.split('|');
return {
userid: parts[0],
roolno: parts[1],
rank: parts[2]
};
});
This would return you:
[
{
userid: 1,
roolno: 1,
rank: 5
},
{
userid: 10,
roolno: 1,
rank: 15
},
]

Categories

Resources