TheWebs
TheWebs

Reputation: 12923

Give me all elements in the array that have the same date, JS

So consider the following data:

{  
   post_views:[  
      {  
         id:1,
         post_id:5,
         ip_address:"xxx",
         created_at:"2016-08-08T22:22:45+0000",
         updated_at:"2016-08-08T22:22:45+0000"
      },
      {  
         id:2,
         post_id:5,
         ip_address:"yyy",
         created_at:"2016-08-08T22:23:00+0000",
         updated_at:"2016-08-08T22:23:00+0000"
      },
      ...
   ]
}

How would get I get all elements that match: 2016-08-08 ??

What have you tried?

Lodashes, filter:

  let datesThatMatch = filter(this.state.data.post_views, (views) => {
    return moment(views.created_at).format('MMMM Do YYYY') === moment(views.created_at).format('MMMM Do YYYY')
  });

  console.log(datesThatMatch);

I don't care about what time of day they were created at, just as long as the day they were created on match.

help?

Update

I just realized I am also going about this all wrong because while I only showed you a portion of the data, there are hundreds of these objects i the array (if not thousands) and the goal is to say, ok there are 16 matches for 2016-08-08, 50 matches for x date, 14 matches for y date which adds to the complexity of this filter.

Upvotes: 0

Views: 608

Answers (4)

user3094755
user3094755

Reputation: 1641

How about...

let post_views = [  
      {  
         id:1,
         post_id:5,
         ip_address:"xxx",
         created_at:"2016-08-08T22:22:45+0000",
         updated_at:"2016-08-08T22:22:45+0000"
      },
      {  
         id:2,
         post_id:5,
         ip_address:"yyy",
         created_at:"2016-08-08T22:23:00+0000",
         updated_at:"2016-08-08T22:23:00+0000"
      }
   ]
  
let looking_for = new RegExp('2016-08-08')
 
let result = post_views.filter(view => looking_for.test(view.created_at) || looking_for.test(view.updated_at) )

let summary = result.reduce((prev,view) => { 
  
                  let created_at = view.created_at.split('T')[0];  
                  let updated_at = view.updated_at.split('T')[0];
  
                      prev.created_at[created_at] = prev.created_at[created_at] || 0;
                      prev.updated_at[updated_at] = prev.updated_at[updated_at] || 0;
                      prev.created_at[created_at]++;
                      prev.updated_at[updated_at]++;
  
                      return prev;  
                  },{ created_at: {}, updated_at: {} })

console.log(result);

console.log(summary);

Upvotes: 0

dmoo
dmoo

Reputation: 1529

I think groupBy is a better alternative based on your update:

var data = {  
   post_views:[  
      {  
         id:1,
         post_id:5,
         ip_address:"xxx",
         created_at:"2016-08-08T22:22:45+0000",
         updated_at:"2016-08-08T22:22:45+0000"
      },
      {  
         id:2,
         post_id:5,
         ip_address:"yyy",
         created_at:"2016-08-08T22:23:00+0000",
         updated_at:"2016-08-08T22:23:00+0000"
      },
      {  
         id:3,
         post_id:5,
         ip_address:"zzz",
         created_at:"2016-08-12T20:15:00+0000",
         updated_at:"2016-08-12T21:20:00+0000"
      },
   ]
}
     
let groupedDatesThatMatch = _.groupBy(data.post_views, function(views) {
     return moment(views.created_at).format('MMMM Do YYYY')
});
     
console.log(groupedDatesThatMatch);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.2/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>

You get an object of arrays out the other end

Upvotes: 2

Trasiva
Trasiva

Reputation: 494

After some finagling, I managed to come up with a solution that uses dateformat and allows you to customize the date on the fly easily. This uses no libraries, and straight ES6. If you run the snippet, you'll see that your dates match and are stored.

const arr = {  
   post_views:[  
      {  
         id:1,
         post_id:5,
         ip_address:"xxx",
         created_at:"2016-08-08T22:22:45+0000",
         updated_at:"2016-08-08T22:22:45+0000"
      },
      {  
         id:2,
         post_id:5,
         ip_address:"yyy",
         created_at:"2016-08-08T22:23:00+0000",
         updated_at:"2016-08-08T22:23:00+0000"
      },
      {  
         id:3,
         post_id:5,
         ip_address:"yyy",
         created_at:"2016-08-09T22:23:00+0000",
         updated_at:"2016-08-08T22:23:00+0000"
      },
   ]
}
const filterDate = new Date(2016, 08, 08);

function parseDate(date) {
  const dateString = date.split("T")[0].split('-'); //Get just the date portion, and then split that into an array.
  const newDate = new Date(Number(dateString[0]), Number(dateString[1]), Number(dateString[2])) //Make the new date object
  return newDate;
}

let myMatches = arr.post_views.filter(thisDate => parseDate(thisDate.created_at).getTime() == filterDate.getTime());

console.log(myMatches);

Upvotes: 0

Jerome Anthony
Jerome Anthony

Reputation: 8021

You can build a "reverse lookup table" (i.e, indicates where each key occurs) Following is a sample demo;

 var a = [1,1,2,3,4,5,6,6,7];                                                                                                                           
 var reverseIndex = new Map();
 a.every((cVal, i, a) => {
   var existing = reverseIndex.has(cVal) ? reverseIndex.get(cVal) : [];
   existing.push(i);
   reverseIndex.set(cVal, existing);
   return true;
 });

console.log(reverseIndex);

Upvotes: 0

Related Questions