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
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)
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.
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.
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)
<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
},
]