got a array of objects and need to filter this by 2 criterias. One of those criterias is an index counting up.
let data =
[{"hour": 1, "dayIndex": 0, "value": "something"},
{"hour": 1, "dayIndex": 1, "value": "something"},
{"hour": 1, "dayIndex": 3, "value": "something"},
{"hour": 2, "dayIndex": 0, "value": "something"},
{"hour": 2, "dayIndex": 1, "value": "something"},
// and so on
]
I need an array of objects filtered by "hour" and ascending "dayIndex" and it is important that for missing dayIndexes an empty object is created. So for hour=1 I would need this:
let hourOneArray =
[
{"hour" : 1, "dayIndex": 0, "value": "something"},
{"hour" : 1, "dayIndex": 1, "value": "something"},
{}, //empty because dayIndex 2 is missing
{"hour" : 1, "dayIndex": 3, "value": "something"},
{}, //empty because dayIndex 4 is missing
]
My approach was:
for(let i = 0; i < 4; ++i){
hourOneArray = data.filter((arg) => {
return ((arg.hour === 1) && (arg.dayIndex === i));
})
}
Thanks in advance
Here's a quick and clean solution to filter all of them by hour, filling in blank days. Make use of map and reduce :D
let data =
[{"hour": 1, "dayIndex": 0, "value": "something"},
{"hour": 1, "dayIndex": 1, "value": "something"},
{"hour": 1, "dayIndex": 3, "value": "something"},
{"hour": 2, "dayIndex": 0, "value": "something"},
{"hour": 2, "dayIndex": 1, "value": "something"},
// and so on
]
let defaultArr = [];
data.forEach(val => defaultArr.push({}));
let output = data.reduce((hash, val) => {
let hour = val.hour;
let dayIndex = val.dayIndex;
if(!hash[hour]) hash[hour] = defaultArr.map(val => val);
hash[hour][dayIndex] = val;
return hash;
}, {})
console.log(output);
You can try following
let data = [{"hour": 1, "dayIndex": 0, "value": "something"},{"hour": 1, "dayIndex": 1, "value": "something"},{"hour": 2, "dayIndex": 0, "value": "something"},{"hour": 2, "dayIndex": 1, "value": "something"},{"hour": 1, "dayIndex": 3, "value": "something"}];
// Sort the array by hour and dayIndex
data.sort((a,b) => a.hour - b.hour || a.dayIndex - b.dayIndex);
function getHourData(hour) {
// Get the hour data
var hourData = data.filter((a) => a.hour === hour);
// Now, iterate till the maximum dayIndex of the filtered array
for (let i = 0; i < hourData[hourData.length -1].dayIndex; i++) {
// If the index is different from dayIndex, count it as missing and add it to the array
if(i !== hourData[i].dayIndex) hourData.splice(i,0, {});
}
// return result
return hourData;
}
console.log(getHourData(1));
let data =
[{"hour": 1, "dayIndex": 0, "value": "something"},
{"hour": 1, "dayIndex": 1, "value": "something"},
{"hour": 1, "dayIndex": 3, "value": "something"},
{"hour": 2, "dayIndex": 0, "value": "something"},
{"hour": 2, "dayIndex": 1, "value": "something"}]
data= data.sort((a,b)=>a.dayIndex-b.dayIndex);
data = data.map(val=>val.hour == 1?val:{});
console.log(data);
You can reduce into an object indexed by dayIndex, then add the objects for each missing day, no sorting needed (O(n)):
const input =
[{"hour": 1, "dayIndex": 0, "value": "something"},
{"hour": 1, "dayIndex": 1, "value": "something"},
{"hour": 1, "dayIndex": 3, "value": "something"},
{"hour": 2, "dayIndex": 0, "value": "something"},
{"hour": 2, "dayIndex": 1, "value": "something"},
];
const [groupedByDay, haveDays] = input
.reduce(([groupedByDay, haveDays], item) => {
const { hour, dayIndex } = item;
if (hour === 1 && !groupedByDay[dayIndex]) {
groupedByDay[dayIndex] = item;
haveDays.push(dayIndex);
}
return [groupedByDay, haveDays];
}, [{}, []]);
const length = Math.max(...haveDays) + 1;
const hourOneArray = Array.from({ length }, (_, i) => (
groupedByDay[i] ? groupedByDay[i] : {}
));
console.log(hourOneArray);
Related
im using JSON to return an array.
Json:
const data = [{
"week": 1,
"lost": 10,
"recovery_timespan": [{
"week": 2,
"count": 1
}, {
"week": 3,
"count": 0
}],
"netLost": 10,
"netReturned": 20
}, {
"week": 2,
"lost": 7,
"recovery_timespan": [{
"week": 3,
"count": 1
}, {
"week": 4,
"count": 3
}],
"netLost": 30,
"netReturned": 200
}, {
"week": 3,
"lost": 8,
"recovery_timespan": [{
"week": 4,
"count": 1
}],
"netLost": 50,
"netReturned": 40
}];
i need to get the data into a array with lost,counts of recovery_timespan,netLost,netReturned.
Expected Output:
[ [ 10, 1, 0, 10, 20 ],
[ 7, 1, 3, 30, 200 ],
[ 8, 1, 50, 40 ] ]
My approach:
const result = data.map(({lost, recovery_timespan,netLost,netReturned}) => [
lost,
...recovery_timespan.map(({count}) => count),
,netLost,netReturned
]);
console.log(result);
and this return array with <1 empty item>:
[ [ 10, 1, 0, <1 empty item>, 10, 20 ],
[ 7, 1, 3, <1 empty item>, 30, 200 ],
[ 8, 1, <1 empty item>, 50, 40 ] ]
Wha is the issue here?
Why am i getting <1 empty item>
You have an extra comma:
const result = data.map(({lost, recovery_timespan,netLost,netReturned}) => [
lost,
...recovery_timespan.map(({count}) => count),
here ---> ,netLost,netReturned
]);
Just remove it.
You have an additional , after the nested map:
const result = data.map(({lost, recovery_timespan,netLost,netReturned}) => [
lost,
...recovery_timespan.map(({count}) => count), // <--
,netLost,netReturned
//^--
]);
That creates a hole in the array. That's why you are seeing <1 empty item> in the output
console.log([1,,2])
const res = data.map((el) => [
el.lost,
...el.recovery_timespan.map((timespan) => timespan.count),
/* extra comma here --> */, el.netLost,
el.netReturned
])
[ [ 10, 1, 0, 10, 20 ], [ 7, 1, 3, 30, 200 ], [ 8, 1, 50, 40 ] ]
Not completly sure, but maybe try this.
...recovery_timespan.map(({count}) => count.count)
I have the array:
array = [
{
"id": 1,
"Price": 100,
"Item": {"id": 1, Name: "A"},
"Date": {"id": 1, Start: "202001"}
},
{
"id": 2,
"Price": 200,
"Item": {"id": 1, Name: "A"},
"Date": {"id": 2, Start: "202002"}
},
{
"id": 3,
"Price": 300,
"Item": {"id": 3, Name: "B"},
"Date": {"id": 2, Start: "202002"}
}
]
And I want to be able to sum the values for a given period, as shown in the table:
ITEM
202002
202003
TOTAL
A
100
200
300
B
300
300
TOTAL
100
500
600
Any suggestion? Thank!
have a look at this, it will start you down the right path
var aHolder = 0;
for(var i = 0; i<array.length; i++){
if(array[i].Date.Start === '202002') {
aHolder = aHolder + array[i].Price;
}
}
console.log(aHolder);
I have old and entity arrays:
var old = [
{
"id": 3,
"entity_type_id": 1,
"product_id": 4,
"name": "test1",
"acreage": 100,
"yield": 20,
"worth": 30
},
{
"id": 4,
"entity_type_id": 1,
"product_id": 4,
"name": "test2",
"acreage": 10,
"yield": 20,
"worth": 0
},
{
"id": 5,
"entity_type_id": 3,
"product_id": 5,
"name": "test3",
"acreage": 20,
"yield": 20,
"worth": 40
}
]
var entity = [
{"id": 1, "name": "a1"},
{"id": 2, "name": "a2"},
{"id": 3, "name": "a3"}
]
I hope to get the following data:
var newArr = [
{
"id": 3,
"entity_type_id": 1,
"product_id": 4,
"name": "test1",
"acreage": 110,
"yield": 40,
"worth": 30,
"entity_type_1": 2, // The total amount of entity_type_id (entity_type_id: 1)
"entity_type_2": 0,
"entity_type_3": 0
},
{
"id": 5,
"entity_type_id": 3,
"product_id": 5,
"name": "test3",
"acreage": 20,
"yield": 20,
"worth": 40,
"entity_type_1": 0,
"entity_type_2": 0,
"entity_type_3": 1 // The total amount of entity_type_id (entity_type_id: 3)
}
]
console.log(newArr)
I tried the following code and got some data. I'm not sure if there will be any exceptions or errors.
What's more, I don't know how to deal with the entity array data. Can someone help me solve this problem and get the result I expect?
Thank you very much !
function mergeArr(arr) {
const temp = []
arr.forEach((dataItem) => {
if (temp.length) {
let filterValue = temp.filter((items) => {
return items.product_id === dataItem.product_id
})
if (filterValue.length) {
temp.forEach((n) => {
if (n.product_id === filterValue[0].product_id) {
n.yield = dataItem.yield + filterValue[0].yield
n.acreage = dataItem.acreage + filterValue[0].acreage
n.worth = dataItem.worth + filterValue[0].worth
}
})
} else {
temp.push(dataItem)
}
} else {
temp.push(dataItem)
}
})
return temp
}
Youi could find the object and sum the wanted properties. For entity take another loop and map new entries and build a new object from it for spreading.
var old = [{ id: 3, entity_type_id: 1, product_id: 4, name: "test1", acreage: 100, yield: 20, worth: 30 }, { id: 4, entity_type_id: 1, product_id: 4, name: "test2", acreage: 10, yield: 20, worth: 0 }, { id: 5, entity_type_id: 3, product_id: 5, name: "test3", acreage: 20, yield: 20, worth: 40 }],
entity = [{ id: 1, name: "a1" }, { id: 2, name: "a2" }, { id: 3, name: "a3" }],
entityTypes = Object.fromEntries(entity.map(({ id }) => ['entity_type_' + id, 0])),
result = old.reduce((r, o) => {
let temp = r.find(q => q.product_id === o.product_id);
if (!temp) r.push(temp = { ... o, ...entityTypes });
else ['acreage', 'yield', 'worth'].forEach(k => temp[k] += o[k]);
temp['entity_type_' + o.entity_type_id]++;
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This question already has answers here:
Get the sum of all specified elements in an array of objects
(5 answers)
Closed 3 years ago.
i am trying to return the sum of the first 4 grid values from the object below (expected output 5)
[
{
"id": 1,
"grid": 1
},
{
"id": 2,
"grid": 2
},
{
"id": 3,
"grid": 1
},
{
"id": 4,
"grid": 1
},
{
"id": 5,
"grid": 1
}
]
data.map(item => {
console.log(item.grid);
});
Relatively new with .map, I would usually use a forwhile iterator but wondered if someone could suggest a more es6 style pattern for solving the problem.
You can use .slice() to cut the Array down to the Elements you want, and then .reduce() to sum up; getting the grid value with Destructuring
const data = [
{"id": 1, "grid": 1},
{"id": 2, "grid": 2},
{"id": 3, "grid": 1},
{"id": 4, "grid": 1},
{"id": 5, "grid": 1}
];
const result = data.slice(0, 4).reduce((a, {grid}, i) => {
return a += Number(grid);
}, 0);
console.log(result)
use slice to get first 4 objects from array and then use reduce to sum the grid.
const input = [{
"id": 1,
"grid": 1
},
{
"id": 2,
"grid": 2
},
{
"id": 3,
"grid": 1
},
{
"id": 4,
"grid": 1
},
{
"id": 5,
"grid": 1
}
];
console.log(input.slice(0, 4).reduce((a, {
grid
}) => a + grid, 0));
I have the following object inside an array:-
[
{"score": 5, "question": 0, "weight": 2},
{"score": 4, "question": 1, "weight": 2},
{"score": 3, "question": 0, "weight": 4},
{"score": 4, "question": 1, "weight": 4},
{"score": 2, "question": 2, "weight": 4},
{"score": 8, "question": 0, "weight": 2}
]
I am trying to loop through the array so I have the following output, so I am able to run some math against the results:-
[
[
{"score": 5, "question": 0, "weight": 2},
{"score": 4, "question": 1, "weight": 2}
],
[
{"score": 3, "question": 0, "weight": 4},
{"score": 4, "question": 1, "weight": 4},
{"score": 2, "question": 2, "weight": 4}
],
[
{"score": 8, "question": 0, "weight": 2}
]
];
Is there a dynamic way I am able to get array1 to look like array2?
I am using flat JS for this please no jQuery answers.
Thanks in advance.
** Note **
Sometimes each section will have more or less values, this is why I require it to be dynamic.
You can do this with reduce() method you just need to keep track of current index for final array.
const data =[
{score: 5, question: 0, weight: 2},
{score: 4, question: 1, weight: 2},
{score: 3, question: 0, weight: 4},
{score: 4, question: 1, weight: 4},
{score: 2, question: 2, weight: 4},
{score: 8, question: 0, weight: 2}
]
const result = data.reduce(function(r, e, i) {
if(i == 0) r = {values: [], counter: 0}
if(e.question == 0 && i != 0) r.counter++
if(!r.values[r.counter]) r.values[r.counter] = [e]
else r.values[r.counter].push(e)
return r;
}, {}).values
console.log(result)
You could check weight and if different, then take a new group.
var data = [{ score: 5, question: 0, weight: 2 }, { score: 4, question: 1, weight: 2 }, { score: 3, question: 0, weight: 4 }, { score: 4, question: 1, weight: 4 }, { score: 2, question: 2, weight: 4 }, { score: 8, question: 0, weight: 2 }],
grouped = data.reduce(function (r, o, i, a) {
if ((a[i - 1] || {}).weight !== o.weight) {
r.push([]);
}
r[r.length - 1].push(o);
return r;
}, []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use Array.reduce() to convert the 1st to the 2nd array. Whenever the current object weight doesn't match lastWeight, add another subarray. Always push the current item to the last subarray:
const arr = [
{score: 5, question: 0, weight: 2},
{score: 4, question: 1, weight: 2},
{score: 3, question: 0, weight: 4},
{score: 4, question: 1, weight: 4},
{score: 2, question: 2, weight: 4},
{score: 8, question: 0, weight: 2}
];
let lastWeight = null;
const result = arr.reduce((r, o) => {
if(lastWeight === null || o.weight !== lastWeight) {
lastWeight = o.weight;
r.push([]);
}
r[r.length - 1].push(o);
return r;
}, []);
console.log(result);
var oldA = [
{"score": 5, "question": 0, "weight": 2},
{"score": 4, "question": 1, "weight": 2},
{"score": 3, "question": 0, "weight": 4},
{"score": 4, "question": 1, "weight": 4},
{"score": 2, "question": 2, "weight": 4},
{"score": 8, "question": 0, "weight": 2}
];
var newA = [];
var prevW = 0;
var prevA;
for (var i = 0; i < oldA.length; i++) {
if (oldA[i].weight != prevW) {
prevA = [];
newA.push(prevA);
prevW = oldA[i].weight;
}
prevA.push(oldA[i]);
}
console.log(newA);
You can use array#reduce to group your array. Check if the value of question is 0 then push a new array and add the object to it.
var data = [ {"score": 5, "question": 0, "weight": 2}, {"score": 4, "question": 1, "weight": 2}, {"score": 3, "question": 0, "weight": 4}, {"score": 4, "question": 1, "weight": 4}, {"score": 2, "question": 2, "weight": 4}, {"score": 8, "question": 0, "weight": 2}],
result = data.reduce((r,o) => {
if(o.question == 0)
r.push([]);
r[r.length - 1].push(o);
return r;
},[]);
console.log(result);
let scores = [
{"score": 5, "question": 0, "weight": 2},
{"score": 4, "question": 1, "weight": 2},
{"score": 3, "question": 0, "weight": 4},
{"score": 4, "question": 1, "weight": 4},
{"score": 2, "question": 2, "weight": 4},
{"score": 8, "question": 0, "weight": 2}
]
let groupedScores = [], group = [];
scores.forEach((entry) => {
if(entry.question === 0) {
if (group.length) {
groupedScores.push(group);
}
group = [];
}
group.push(entry);
})
groupedScores.push(group)
console.log(groupedScores)
A bit simplified if splitting by just question: 0 :
data = [ { score: 5, question: 0, weight: 2 }, { score: 4, question: 1, weight: 2 },
{ score: 3, question: 0, weight: 4 }, { score: 4, question: 1, weight: 4 },
{ score: 2, question: 2, weight: 4 }, { score: 8, question: 0, weight: 2 } ]
result = data.reduce((r, v) => (v.question ? r[r.length-1].push(v) : r.push([v]), r), [])
console.log( result )