Sum Array Value Based on Object Keys [duplicate] - javascript

How would one take a JavaScript array of objects, such as
objArr = [
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:42},
{key:"Mon Sep 24 2013 00:00:00 GMT-0400", val:78},
{key:"Mon Sep 25 2013 00:00:00 GMT-0400", val:23},
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:54} // <- duplicate key
]
and merge duplicate keys by summing the values?
In order to get something like this:
reducedObjArr = [
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:96},
{key:"Mon Sep 24 2013 00:00:00 GMT-0400", val:78},
{key:"Mon Sep 25 2013 00:00:00 GMT-0400", val:23}
]
I have tried iterating and adding to a new array, but this didn't work:
var reducedObjArr = [];
var item = null, key = null;
for(var i=0; i<objArr.length; i++) {
item = objArr[i];
key = Object.keys(item)[0];
item = item[key];
if(!result[key]) {
result[key] = item;
} else {
result[key] += item;
}
}a

Rather than using a for loop and pushing values, you can directly use map and reduce:
let objArr = [
{key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 42},
{key: 'Mon Sep 24 2013 00:00:00 GMT-0400', val: 78},
{key: 'Mon Sep 25 2013 00:00:00 GMT-0400', val: 23},
{key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 54}
];
// first, convert data into a Map with reduce
let counts = objArr.reduce((prev, curr) => {
let count = prev.get(curr.key) || 0;
prev.set(curr.key, curr.val + count);
return prev;
}, new Map());
// then, map your counts object back to an array
let reducedObjArr = [...counts].map(([key, value]) => {
return {key, value}
})
console.log(reducedObjArr);

You should be assigning each object not found to the result with its .key property.
If it is found, then you need to add its .val.
var temp = {};
var obj = null;
for(var i=0; i < objArr.length; i++) {
obj=objArr[i];
if(!temp[obj.key]) {
temp[obj.key] = obj;
} else {
temp[obj.key].val += obj.val;
}
}
var result = [];
for (var prop in temp)
result.push(temp[prop]);
Also, part of the problem was that you were reusing the item variable to reference the value of .key, so you lost reference to the object.

Simpler reduce than posted elsewhere since it does not use a Map element
const objArr = [
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:42},
{key:"Mon Sep 24 2013 00:00:00 GMT-0400", val:78},
{key:"Mon Sep 25 2013 00:00:00 GMT-0400", val:23},
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:54}];
const output = objArr.reduce((accumulator, cur) => {
let date = cur.key;
let found = accumulator.find(elem => elem.key === date)
if (found) found.val += cur.val;
else accumulator.push(cur);
return accumulator;
}, []);
console.log(output)

You could use a hash table for the grouping by key.
var array = [{ key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 42 }, { key: 'Mon Sep 24 2013 00:00:00 GMT-0400', val: 78 }, { key: 'Mon Sep 25 2013 00:00:00 GMT-0400', val: 23 }, { key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 54}],
grouped = [];
array.forEach(function (o) {
if (!this[o.key]) {
this[o.key] = { key: o.key, val: 0 };
grouped.push(this[o.key]);
}
this[o.key].val += o.val;
}, Object.create(null));
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Another approach is to collect all key/value pairs in a Map and format the final array with Array.from and a callback for the objects.
var array = [{ key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 42 }, { key: 'Mon Sep 24 2013 00:00:00 GMT-0400', val: 78 }, { key: 'Mon Sep 25 2013 00:00:00 GMT-0400', val: 23 }, { key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 54 }],
grouped = Array.from(
array.reduce((m, { key, val }) => m.set(key, (m.get(key) || 0) + val), new Map),
([key, val]) => ({ key, val })
);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

var objArr = [
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:42},
{key:"Mon Sep 24 2013 00:00:00 GMT-0400", val:78},
{key:"Mon Sep 25 2013 00:00:00 GMT-0400", val:23},
{key:"Mon Sep 23 2013 00:00:00 GMT-0400", val:54}]
var targetObj = {};
for (var i = 0; i < objArr.length; i++) {
if (!targetObj.hasOwnProperty(objArr[i].key)) {
targetObj[objArr[i].key] = 0;
}
targetObj[objArr[i].key] += objArr[i].val;
}
console.log(targetObj);

One can use Array#reduce with an object to store the values for each key.
let arr = [{key:'Mon Sep 23 2013 00:00:00 GMT-0400', val:42},{key:'Mon Sep 24 2013 00:00:00 GMT-0400', val:78},{key:'Mon Sep 25 2013 00:00:00 GMT-0400', val:23},{key:'Mon Sep 23 2013 00:00:00 GMT-0400', val:54}];
let res = Object.values(arr.reduce((acc, curr)=>{
(acc[curr.key] = acc[curr.key] || {key: curr.key, val: 0}).val += curr.val;
return acc;
}, {}));
console.log(res);
In newer browsers, logical nullish assignment can be used.
let arr = [{key:'Mon Sep 23 2013 00:00:00 GMT-0400', val:42},{key:'Mon Sep 24 2013 00:00:00 GMT-0400', val:78},{key:'Mon Sep 25 2013 00:00:00 GMT-0400', val:23},{key:'Mon Sep 23 2013 00:00:00 GMT-0400', val:54}];
let res = Object.values(arr.reduce((acc, curr)=>{
(acc[curr.key] ??= {key: curr.key, val: 0}).val += curr.val;
return acc;
}, {}));
console.log(res);

Try this. It should help.
var arr1 = [
{ name: 'besart', value: 12 },
{ name: 'astrit', value: 10 },
{ name: 'astrit', value: 10 },
{ name: 'besar', value: 18 },
{ name: 'besar', value: 3 },
{ name: 'astrit', value: 3 },
{ name: 'besart', value: 3 },
{ name: 'besart', value: 10 },
{ name: 'besar', value: 0 },
];
var arr2 = [];
var emri = "";
var value = 0;
for (var i = 0; i < arr1.length; i++) {
emri = arr1[0].name;
value += arr1[0].value;
for (var j = 1; j < arr1.length; j++) {
if (emri == arr1[j].name) {
value += arr1[j].value;
arr1.splice(j, 1);
j--;
}
}
arr1.splice(0, 1);
arr2[i] = {
name: emri,
value: value
};
value = 0;
}
console.log(arr2);
Below is another solution that uses only one loop (a while loop):
var arr1 = [
{ name: 'besart', value: 12 },
{ name: 'astrit', value: 10 },
{ name: 'astrit', value: 10 },
{ name: 'besar', value: 18 },
{ name: 'besar', value: 3 },
{ name: 'astrit', value: 3 },
{ name: 'besart', value: 3 },
{ name: 'besart', value: 10 },
{ name: 'besar', value: 0 },
];
var arr2 = [];
var emri = "";
var value = 0;
var i = 1;
var j = 0;
while (arr1.length != 0) {
emri = arr1[0].name;
if (emri == arr1[i].name) {
value += arr1[i].value;
arr1.splice(i, 1);
i--;
}
i++;
if (i == arr1.length) {
value += arr1[0].value;
i = 1;
arr2[j] = {
name: emri,
value: value
};
j++;
value = 0;
arr1.splice(0, 1);
}
}
console.log(arr2)

You can also try using the JavaScript linq framework which is exactly same as an SQL statement which is given desired output with less written code and effective and found at linq.js.
var objArr =
[
{key:'Mon Sep 23 2013 00:00:00 GMT-0400', val:42},
{key:'Mon Sep 24 2013 00:00:00 GMT-0400', val:78},
{key:'Mon Sep 25 2013 00:00:00 GMT-0400', val:23},
{key:'Mon Sep 23 2013 00:00:00 GMT-0400', val:54}
];
var aggregatedObject = Enumerable.From(objArr)
.GroupBy("$.key", null,
function (key, g) {
return {
key: key,
contributions: g.Sum("$.val")
}
})
.ToArray();
console.log(aggregatedObject);
<script src="http://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.min.js"></script>
Which is pretty easy as compare to looping.

Recently I needed a similar implementation and I used a similar solution offered by some guy that used the reduce function.
A few days later I wanted to implement something similar by myself and here is the result.
const users = [
{ id: 1, name: 'ernest', spent: 40 },
{ id: 2, name: 'ernest', spent: 40 },
{ id: 3, name: 'astrit', spent: 22 },
{ id: 4, name: 'astrit', spent: 2956 },
{ id: 5, name: 'astrit', spent: 22 },
{ id: 6, name: 'besart', spent: 40 },
{ id: 7, name: 'besart', spent: 100},
{ id: 8, name: 'besart', spent: 4000 }
];
const sum = [];
users.forEach(el => {
if(sum.length === 0) {
delete el.id;
sum.push(el);
}
else
{
const get = () => {
for(let i = 0; i < sum.length; i++) {
if(sum[i].name === el.name) {
return { stat: true, id: i };
}
}
}
let i = get();
if(i) {
sum[i.id].spent += el.spent;
}
else
{
delete el.id;
sum.push(el);
}
}
});
console.log(sum);
Output:
[ { name: 'ernest', spent: 80 }, { name: 'astrit', spent: 3000 }, { name: 'besart', spent: 4140 } ]

Here is an alternative for you, but similar to that of Explosion Pills. It reuses the original array rather than creating a new one or a different object. The sort may not be necessary and will slow things down a little, but it could be removed.
JavaScript
function reduceMyObjArr(arr) {
var temp = {},
index;
for (index = arr.length - 1; index >= 0; index -= 1) {
key = arr[index].key;
if (temp.hasOwnProperty(key)) {
arr[temp[key]].val += arr[index].val;
arr.splice(index, 1);
} else {
temp[key] = index;
}
}
arr.sort(function (a, b) {
if (a.key === b.key) {
return 0;
}
if (a.key < b.key) {
return -1;
}
return 1;
});
return arr;
}
var myObjArr = [{
key: "Mon Sep 23 2013 00: 00: 00 GMT - 0400",
val: 42
}, {
key: "Mon Sep 24 2013 00: 00: 00 GMT - 0400",
val: 78
}, {
key: "Mon Sep 25 2013 00: 00: 00 GMT - 0400",
val: 23
}, {
key: "Mon Sep 23 2013 00: 00: 00 GMT - 0400",
val: 54
}];
reduceMyObjArr(myObjArr);
console.log(myObjArr);
jsFiddle
And a jsperf that compares this (with and without the sort) against the accepted answer. You can improve the performance test by extending the data set.

function sumGroupBy(array, groupColumn, valueColumn) {
var res = []
array.forEach((item) => {
if(res.map((el) => el[groupColumn]).includes(item[groupColumn])) {
res.filter((el) => el[groupColumn] == item[groupColumn])[0][valueColumn] += item[valueColumn]
} else {
eval(`res.push({${groupColumn}: "${item[groupColumn]}", ${valueColumn}: ${item[valueColumn]} })`)
}
});
return res;
}
const pets = [
{type:"Dog", age:12},
{type:"Cat", age:13},
{type:"Dog", age:6},
{type:"Cat", age:18}
];
console.log(sumGroupBy(pets, 'type', 'age' ))
// [ { type: 'Dog', age: 18 }, { type: 'Cat', age: 31 } ]

function mergeDuplicatesBy(array, getKey, mergeWith) {
const buff = {}
array.forEach(function (arrayElement) {
const key = getKey(arrayElement)
const alreadyExistingVal = buff[key]
if (alreadyExistingVal) {
buff[key] = mergeWith(alreadyExistingVal, arrayElement)
} else {
buff[key] = arrayElement
}
})
return Object.values(buff)
}
mergeDuplicatesBy(
arr,
x => x.name,
(x, y) => ({ name: x.name, foo: x.foo + y.foo })
)

Related

How do I group together identical items when mapping over an array of objects?

Given the following array of gigs:
const gigs = [
{
name: ' sat gig 1',
date: 'Sat Dec 10 2022'
},
{
name: ' sat gig 2',
date: 'Sat Dec 10 2022'
},
{
name: ' sun gig 1',
date: 'Sun Dec 11 2022'
},
{
name: ' sun gig 2',
date: 'Sun Dec 11 2022'
},
]
How do I map over it and render the gigs, but grouped by the gig date? I've included the desired output as follows, as well as my own attempt to solve this. I'd prefer to not use lodash.
Sat Dec 10
sat gig 1
sat gig 2
Sun Dec 11
sun gig 1
sun gig 2
Here's my attempt so far:
const gigs = [
{
name: ' sat gig 1',
date: '2022-12-10'
},
{
name: ' sat gig 2',
date: '2022-12-10'
},
{
name: ' sun gig 1',
date: '2022-12-11'
},
{
name: ' sun gig 2',
date: '2022-12-11'
},
]
const gigArray =[]
gigs.map(gig => {
const gigDate = new Date(gig.date)
const gigDateString = gigDate.toString().slice(0,15) //gives date in form 'Sun Dec 11 2022'
gigArray.push({date:gigDateString,name:gig.name})
})
const groupedObj = gigArray.reduce(
(prev, current) => ({
...prev,
[current]: [...(prev[current] || []), current],
}),
{}
);
const groupedObjToArr = Object.values(groupedObj);
Here's a reduce solution that creates an object with the dates as the keys:
const gigs=[{name:"sat gig 1",date:"Sat Dec 10 2022"},{name:"sat gig 2",date:"Sat Dec 10 2022"},{name:"sun gig 1",date:"Sun Dec 11 2022"},{name:"sun gig 2",date:"Sun Dec 11 2022"}];
const result = gigs.reduce((acc, curr) => {
if (acc[curr.date]) {
acc[curr.date].push(curr)
} else {
acc[curr.date] = [curr]
}
return acc;
}, {})
console.log(result)
From there, generating the output is simple:
const gigs=[{name:"sat gig 1",date:"Sat Dec 10 2022"},{name:"sat gig 2",date:"Sat Dec 10 2022"},{name:"sun gig 1",date:"Sun Dec 11 2022"},{name:"sun gig 2",date:"Sun Dec 11 2022"}];
const result = gigs.reduce((acc, curr) => {
if (acc[curr.date]) {
acc[curr.date].push(curr)
} else {
acc[curr.date] = [curr]
}
return acc;
}, {})
Object.keys(result).forEach(key => {
console.log(key)
result[key].forEach(val => console.log(val))
})

obtaining a count after using reduce in Javascript

I'm trying to find a way to count the amount of times the direction is 'IN' or 'Out' after grouping them.
for example in the below data I would like Person and Item tag to be the group and then output how many IN's or OUT's show up based on their unique groups.
const data = [
{
Person: 'Jake',
Item_tag: '124',
date: 'Mon May 11 2020',
direction: 'IN',
},
{
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'IN',
},
{
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'OUT',
},
]
I would expect an output like
Person: Jake Item_tag:123 Incoming: 1 outgoing:1
Person: Jake Item_tag:124 Incoming:1 outgoing:0
Below is what I've tried using reduce, but I couldn't figure out how to get the proper count inside the reduce.
import React from 'react'
type Props = {}
//Data
const data = [
{
Person: 'Jake',
Item_tag: '123',
date: 'Mon May 11 2020',
direction: 'IN',
},
{
Person: 'Mary',
Item_tag: '123',
date: 'Mon May 11 2020',
direction: 'OUT',
},
{
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'IN',
},
{
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'OUT',
},
]
const result = data.reduce((res, current) => {
// build the grouping (Person + Item_tag)
const key = `${current.Person}_${current.Item_tag}`
res[key] = res[key] || {
Person: current.Person,
Item_tag: current.Item_tag,
Count_of_incoming: '0',
Count_of_outgoing: '0',
return res
}, {})
// print values
console.log(Object.values(result))
Any help is appreciated!
You just need one more increment instruction for res[key].Count_of_xxxx, where xxxx depends on current.direction.
A tiny issue: don't inialise these counters as strings, but as numbers.
See the added if..else:
const data = [
{Person: 'Jake',Item_tag: '123',date: 'Mon May 11 2020',direction: 'IN',},
{Person: 'Mary',Item_tag: '123',date: 'Mon May 11 2020',direction: 'OUT',},
{Person: 'Jake',Item_tag: '123',date: 'Tue May 12 2020',direction: 'IN',},
{Person: 'Jake',Item_tag: '123',date: 'Tue May 12 2020',direction: 'OUT',},
];
const result = data.reduce((res, current) => {
// build the grouping (Person + Item_tag)
const key = `${current.Person}_${current.Item_tag}`;
res[key] = res[key] || {
Person: current.Person,
Item_tag: current.Item_tag,
Count_of_incoming: 0,
Count_of_outgoing: 0,
};
if (current.direction === "OUT") {
res[key].Count_of_outgoing++;
} else {
res[key].Count_of_incoming++;
}
return res;
}, {});
// print values
console.log(Object.values(result));
Let's try to group by Person and Item_tag using a separator first. Then using object of objects. Seems appropriate for a more generic solution but for now this works:
const data = [{
Person: 'Jake',
Item_tag: '124',
date: 'Mon May 11 2020',
direction: 'IN',
}, {
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'IN',
}, {
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'OUT',
},
];
var step1 = data.reduce(function(acc, item) {
var key1 = item.Person;
var key2 = item.Item_tag;
acc[key1] = acc[key1] || {};
acc[key1][key2] = acc[key1][key2] || {IN: 0, OUT: 0}
acc[key1][key2][item.direction] = acc[key1][key2][item.direction] + 1
return acc;
}, {})
for (var key1 in step1) {
for (var key2 in step1[key1]) {
console.log(`Person: ${key1} Item_tag:${key2} Incoming: ${step1[key1][key2].IN} outgoing:${step1[key1][key2].OUT}`)
}
}

Array groupby and count

I am trying to get day wise count from below data
example:
{ 'Tue Oct 01 2019': 3, 'Tue Oct 02 2019': 1 }
But I'm not getting the expected result from the below code.
const data = [ { Date: 'Tue Oct 01 2019' },{ Date: 'Tue Oct 01 2019' },{ Date: 'Tue Oct 01 2019' }, { Date: 'Tue Oct 02 2019' } ];
const result = data.reduce((total, value) => {
total[value] = (total[value] || 0) + 1;
return total;
}, {});
console.log(result);
If I understood you correctly, what you want is to group and get count:
const data = [
{ Date: 'Tue Oct 01 2019' },
{ Date: 'Tue Oct 01 2019' },
{ Date: 'Tue Oct 01 2019' },
{ Date: 'Tue Oct 02 2019' }
];
const result = data.reduce((total, {Date}) => {
total[Date] = (total[Date] || 0) + 1;
return total;
}, {});
console.log(result);
value is an Object, use value.Date instead of just value :
const data = [
{ Date: "Tue Oct 01 2019" },
{ Date: "Tue Oct 01 2019" },
{ Date: "Tue Oct 01 2019" },
{ Date: "Tue Oct 02 2019" }
];
const result = data.reduce((total, value) => {
total[value.Date] = (total[value.Date] || 0) + 1;
return total;
}, {});
console.log(result);

Object.values on a realmjs object returns an empty array

Description
I'm trying to convert my realm object to an array as can be seen below in the history method.
class RealmStore {
#observable symptoms = {};
#observable meals = {};
#computed get history(){
return [...Object.values(this.symptoms), ...Object.values(this.meals)];
}
//More methods to populate this.symptoms and this.meals
}
When I log this.symptoms I get the following output in my terminal:
{
'0': {
date: Fri Jun 29 2018 15: 56: 48 GMT + 0200(CEST),
name: 'Regurgitation',
value: 1
},
'1': {
date: Fri Jun 29 2018 15: 58: 09 GMT + 0200(CEST),
name: 'Belching',
value: 1
},
'2': {
date: Fri Jun 29 2018 16: 10: 39 GMT + 0200(CEST),
name: 'Heartburn',
value: 2
},
'3': {
date: Fri Jun 29 2018 23: 30: 36 GMT + 0200(CEST),
name: 'Heartburn',
value: 1
}
}
When I log Object.keys(this.symptoms) I get the following in my terminal:
[ '0', '1', '2', '3' ]
When I log Object.values(this.symptoms) I get the following in my terminal:
[]
This is the only way that this works:
const values = [];
for(let prop in this.symptoms){
if(this.symptoms.hasOwnProperty(prop)){
values.push(this.symptoms[prop])
}
}
console.log(values);
This logs the following in my terminal:
[{
date: Fri Jun 29 2018 15: 56: 48 GMT + 0200(CEST),
name: 'Regurgitation',
value: 1
},
{
date: Fri Jun 29 2018 15: 58: 09 GMT + 0200(CEST),
name: 'Belching',
value: 1
},
{
date: Fri Jun 29 2018 16: 10: 39 GMT + 0200(CEST),
name: 'Heartburn',
value: 2
},
{
date: Fri Jun 29 2018 23: 30: 36 GMT + 0200(CEST),
name: 'Heartburn',
value: 1
}
]
Question:
What is causing the realmjs object to be unable to return an array of values?
Currently unsure as to why Object.values() does not work. I went ahead and used this alternative, which according to some posts may cause performance issues.
Array.from(this.symptoms);

How to count occurrences in an array of objects by date

I'm searching a powerful solution in TypeScript or JavaScript to count occurrences in an array of object. I'd like to do that by Date. (I need it to create some charts)
For example, i have this array :
var arr = [
{date: Wed Jan 20 2016
type: "Apples"},
{date: Mon Feb 29 2016
type: "Peaches"},
{date: Thu Mar 31 2016
type: "Apples"},
{date: Fri Apr 22 2016
type: "Apples"},
{date: Fri Apr 22 2016
type: "Apples"},
{date: Fri Apr 22 2016
type: "Apples"},
{date: Fri Apr 22 2016
type: "Strawberries"}
]
The result I would like to have is the next one :
var arr2 = [
{date: Wed Jan 20 2016
type: ["Apples", 1]},
{date: Mon Feb 29 2016
type: ["Peaches",1]},
{date: Thu Mar 31 2016
type: ["Apples",1]},
{date: Fri Apr 22 2016
type: ["Apples",3],["Strawberries",1]}
]
I don't know why, but I can't find a good solution, I'm working on it during some days...
If anybody knows a trick, a function, or something else?
try this
First create a map
var map = {}; arr.forEach(function(val){
map[val.date] = map[val.date] || {};
map[val.date][val.type] = map[val.date][val.type] || 0;
map[val.date][val.type]++;
});
Now get the output
var output = Object.keys(map).map(function(key){
var tmpArr = [];
for(var type in map[key])
{
tmpArr.push( [ type, map[key][type] ] )
}
return { date : key, type: tmpArr };
})
DEMO
var arr = [
{date: "Wed Jan 20 2016",
type: "Apples"},
{date: "Mon Feb 29 2016",
type: "Peaches"},
{date: "Thu Mar 31 2016",
type: "Apples"},
{date: "Fri Apr 22 2016" ,
type: "Apples"},
{date: "Fri Apr 22 2016" ,
type: "Apples"},
{date: "Fri Apr 22 2016" ,
type: "Apples"},
{date: "Fri Apr 22 2016" ,
type: "Strawberries"}
]
var map = {}; arr.forEach(function(val){
map[val.date] = map[val.date] || {};
map[val.date][val.type] = map[val.date][val.type] || 0;
map[val.date][val.type]++;
});
var output = Object.keys(map).map(function(key){
var tmpArr = [];
for(var type in map[key])
{
tmpArr.push( [ type, map[key][type] ] )
}
return { date : key, type: tmpArr };
})
document.body.innerHTML += JSON.stringify(output,0,4);
should work like this:
var x = new Date().getTime(),
filtered = arr.filter( function (obj) { return obj.date.getTime() >= x }),
occurenceCount = filtered.length;
I use getTime() to convert the dates to integer, since I had odd behaviour comparing Date objects bevor. arr2 would contain all dates after x (in this exampale NOW) and count would return the number of elements contained in arr2.
With a proper date format like here with ISO date, and a temporary object, you could use a Array#forEach loop and return the wanted result. It works in a single loop.
var array = [{ date: '2016-01-20', type: "Apples" }, { date: '2016-02-29', type: "Peaches" }, { date: '2016-03-31', type: "Apples" }, { date: '2016-04-22', type: "Apples" }, { date: '2016-04-22', type: "Apples" }, { date: '2016-04-22', type: "Apples" }, { date: '2016-04-22', type: "Strawberries" }],
grouped = [];
array.forEach(function (a) {
var key = a.date + '|' + a.type;
if (!this[a.date]) {
this[a.date] = { date: a.date, type: [] };;
grouped.push(this[a.date]);
}
if (!this[key]) {
this[key] = [a.type, 0];
this[a.date].type.push(this[key]);
}
this[key][1]++;
}, Object.create(null));
document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');
Filter the array and check the date in the filter function.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
function findItemsByDate(value) {
// find if an item already exists with the date index
var dateIndex = arr2.findIndex(findDateIndex);
// create an array or use the existing one based on result
if(dateIndex === -1){
var dateArray = []
}else{
dateArray = arr2[dateIndex];
}
// find the type object based on the input type and add to it, or create a new one.
if(dateArray.type.hasOwnProperty(value.type)){
dateArray.type[value.type] += 1;
}else{
dateArray.type[value.type] = 1;
}
}
// utility function to see if an item already exists in the new array with the key for the date.
function findDateIndex(item, index, arr){
if(item.date = "Thu Mar 31 2016"){
alert("Has Data")
return index;
}
return -1;
}
This will return a slightly different, but more managable result than you are looking for.
var arr2 = [
{date: "Wed Jan 20 2016", type: ["Apples", 1]},
{date: "Mon Feb 29 2016",type: ["Peaches",1]},
{date: "Thu Mar 31 2016", type: ["Apples",1]},
{date: "Fri Apr 22 2016", type: {"Apples":3,"Strawberries":1}}
]

Categories

Resources