I have months values like below
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var objects = {
April:0,
August:4182,
December:0,
February:0,
January:1,
July:2,
June:0,
March:0,
May:0,
November:0,
October:0,
September:1518
}
How to sort the objects based on the months array?
Try with:
var output = [];
for (var k in months) {
var month = months[k];
output.push({name: month, value: objects[month]});
}
It will returns you ordered list of objects that contain name and value keys which have proper month name and its value.
var values = [];
for(var i = 0; i < months.length; i++) {
vals.push(objects[months[i]]);
}
This way you get the object properties' values ordered by the months array.
You can't sort the properties in an object, because the order of the properties is not maintained. If create an object like that, then loop out the properties, you will see that the properties may not be returned in the same order that you put them in the object, and different browsers will return the properties in differend order.
Make the object an array, so that it can maintain the order of the values, and make the lookup array an object so that you can efficiently map a string to a numeric value:
var months = {
January: 1,
February: 2,
March: 3,
April: 4,
May: 5,
June: 6,
July: 7,
August: 8,
September: 9,
October: 10,
November: 11,
December: 12
};
var objects = [
{ name: 'April', value: 0 },
{ name: 'August', value: 4182 },
{ name: 'December', value: 0 },
{ name: 'February', value: 0 },
{ name: 'January', value: 1 },
{ name: 'July', value: 2 },
{ name: 'June', value: 0 },
{ name: 'March', value: 0 },
{ name: 'May', value: 0 },
{ name: 'November', value: 0 },
{ name: 'October', value: 0 },
{ name: 'September', value: 1518 }
];
Now you can sort the array using the object:
objects.sort(function(x,y) { return months[x.name] - months[y.name]; });
Demo: http://jsfiddle.net/7eKfn/
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.
For example, I have two arrays like these.
const dateArray = ['January', 'February', 'March', 'April', 'May', 'June']
const InfoArray = [
{ Date : '2022-01', Active: 1 },
{ Date : '2022-02', Active: 12 },
{ Date : '2022-03', Active: 25 },
{ Date : '2022-04', Active: 33 },
{ Date : '2022-05', Active: 120 },
{ Date : '2022-06', Active: 335 },
]
However, I want combined these two arrays into an array of objects.
const result = [
{ month: 'January', Active: 1 },
{ month: 'February', Active: 12 },
{ month: 'March', Active: 25 },
{ month: 'April', Active: 33 },
{ month: 'May', Active: 120 },
{ month: 'June', Active: 335 },
]
I looked for some information, and did like
const makeObjectWithTwoArray = () => {
let chartObj = {}
dateArray.forEach((element, index) => {
chartObj[element] = infoArray[index]
})
return chartObj
}
however doesn't work at all. (of course because each array can't have same keys with the code.)
Your help will be much appreciated.
You can use the function Array.prototype.map as follows:
const dateArray = ['January', 'February', 'March', 'April', 'May', 'June']
const InfoArray = [
{ Date : '2022-01', Active: 1 },
{ Date : '2022-02', Active: 12 },
{ Date : '2022-03', Active: 25 },
{ Date : '2022-04', Active: 33 },
{ Date : '2022-05', Active: 120 },
{ Date : '2022-06', Active: 335 },
];
const result = InfoArray.map(({Date, Active}) => {
const [_, month] = Date.split("-");
return {Active, month: dateArray[[Number(month) - 1]]};
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
const dateArray = ['January', 'February', 'March', 'April', 'May', 'June']
const InfoArray = [
{ Date : '2022-01', Active: 1 },
{ Date : '2022-02', Active: 12 },
{ Date : '2022-03', Active: 25 },
{ Date : '2022-04', Active: 33 },
{ Date : '2022-05', Active: 120 },
{ Date : '2022-06', Active: 335 },
]
const result = InfoArray.map(item => {
const monthNumber = item.Date.split('-')[1]
const month = dateArray[+monthNumber - 1]
return {
Active: item.Active,
month
}
})
console.log(result)
You Actually don't need the dateArray you can just extract the month name from the Date property.
const InfoArray = [
{ Date : '2022-01', Active: 1 },
{ Date : '2022-02', Active: 12 },
{ Date : '2022-03', Active: 25 },
{ Date : '2022-04', Active: 33 },
{ Date : '2022-05', Active: 120 },
{ Date : '2022-06', Active: 335 },
]
let result = InfoArray.map(e => ({
month: new Date(e.Date).toLocaleString('default', {month: 'long'}),
Active: e.Active
}))
console.log(result)
Another alternative is using .reduce.
Note: I didn't return [...arr, {...}] implicitly since it would have created a different array on each iteration. return arr is better if you are going to have a large data (potenitally)
const dateArray = ['January', 'February', 'March', 'April', 'May', 'June']
const InfoArray = [
{ Date : '2022-01', Active: 1 },
{ Date : '2022-02', Active: 12 },
{ Date : '2022-03', Active: 25 },
{ Date : '2022-04', Active: 33 },
{ Date : '2022-05', Active: 120 },
{ Date : '2022-06', Active: 335 },
]
const combined = InfoArray.reduce((arr, {Date, Active}) => {
arr.push({
Date: dateArray[Number(Date.split("-")[1]) -1],
Active
})
return arr
}, [])
console.log("combined: ", combined)
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
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)