-1

I'm working through gathering information from multiple arrays but I've hit a stumbling block. I need to be able to determine how many days were spent in each city. The trouble is I can't figure out a way to count time entries that span a single day as 1 day. In the below the first two San Diego entries should result in a single day since both logs happened within the same day.

timeLogs = [
    {'city':'San Diego','date':'2017-03-21T18:52:00.984Z'},
    {'city':'San Diego','date':'2017-03-21T12:13:00.984Z'},
    {'city':'San Diego','date':'2017-03-19T11:02:00.984Z'},
    {'city':'Boulder','date':'2017-02-12T11:29:00.984Z'}
]

What I'm after is the following resulting array based on the above:

daysPerCity = [
    {'San Diego':'2'},
    {'Boulder':'1'}
]

Currently I'm working on a loop which coverts the dates to strings and then checks for equality, if the same I'm trying to not increment the city in the new array but I'm stuck when it hits the very first instance of a city...

Mike
  • 3
  • 1
  • check [How do I get the number of days between two dates in JavaScript?](http://stackoverflow.com/questions/542938/how-do-i-get-the-number-of-days-between-two-dates-in-javascript) up – Redu Mar 22 '17 at 20:10
  • also you can use [moment.js](https://momentjs.com/docs/#/displaying/difference/) – ArtemSky Mar 22 '17 at 20:17

2 Answers2

-1

You can use Array methods like reduce and map to build an object containing unique days grouped by city, and then use Object.keys(...).length to get the number of distinct days.

var timeLogs = [
    { city: 'San Diego', date: '2017-03-21T18:52:00.984Z' },
    { city: 'San Diego', date: '2017-03-21T12:13:00.984Z' },
    { city: 'San Diego', date: '2017-03-19T11:02:00.984Z' },
    { city: 'Boulder', date: '2017-02-12T11:29:00.984Z' }
]

var daysPerCity = timeLogs.reduce(function (map, e) {
  (map[e.city] = map[e.city] || {})[e.date.slice(0, 10)] = true
  return map
}, {})

Object.keys(daysPerCity).forEach(function (k) {
  this[k] = Object.keys(this[k]).length
}, daysPerCity)

console.log(daysPerCity)
gyre
  • 16,369
  • 3
  • 37
  • 47
-1

You could use this ES6 code:

const timeLogs = [
    {'city':'San Diego','date':'2017-03-21T18:52:00.984Z'},
    {'city':'San Diego','date':'2017-03-21T12:13:00.984Z'},
    {'city':'San Diego','date':'2017-03-19T11:02:00.984Z'},
    {'city':'Boulder','date':'2017-02-12T11:29:00.984Z'}
];

const result = Object.assign({}, ...Array.from(
    timeLogs.reduce( (acc, {city, date}) => {
        (acc.get(city) || acc.set(city, new Set).get(city))
            .add(date.substr(0, 10));
        return acc;
    }, new Map),
    ([city, days]) => ({ [city]: days.size })
));

console.log(result);
trincot
  • 317,000
  • 35
  • 244
  • 286