Sort through an array, and push duplicates into a new array - javascript

I have an array of objects with dates. What I want to do is select all objects with the same date value and push those into a new array.
here's my code.
var posts = [
{
"userid": 1,
"rating": 4,
"mood": "happy",
"date": "2017-05-24T04:00:00.000Z"
},
{
"userid": 1,
"rating": 3,
"mood": "happy",
"date": "2017-05-24T04:00:00.000Z"
},
{
"userid": 1,
"rating": 3,
"mood": "angry",
"date": "2017-05-25T04:00:00.000Z"
},
{
"userid": 1,
"rating": 5,
"mood": "hungry",
"date": "2017-05-25T04:00:00.000Z"
}]
var may25=[];
for(i=0;i < posts.length;i++){
if(posts[i].date === posts[i].date){
may25.push(posts[i].date)
}
}

You could slice the date from the string and take it as key for an object for grouping items by date. The result is an object with all grouped objects.
var posts = [{ userid: 1, rating: 4, mood: "happy", date: "2017-05-24T04:00:00.000Z" }, { userid: 1, rating: 3, mood: "happy", date: "2017-05-24T04:00:00.000Z" }, { userid: 1, rating: 3, mood: "angry", date: "2017-05-25T04:00:00.000Z" }, { userid: 1, rating: 5, mood: "hungry", date: "2017-05-25T04:00:00.000Z" }],
groups = Object.create(null);
posts.forEach(function (o) {
var date = o.date.slice(0, 10);
groups[date] = groups[date] || [];
groups[date].push(o)
});
console.log(groups);
.as-console-wrapper { max-height: 100% !important; top: 0; }

If you are just looking for may 25 dates (as your question suggests):
var may25=[];
for (i=0;i < posts.length;i++) {
if (posts[i].date === "2017-05-25T04:00:00.000Z") {
may25.push(posts[i].date)
}
}

You may want to create an object that contains date => event arrays :
var result=posts.reduce((obj,event)=>((obj[event.date]=obj[event.date] || []).push(event),obj),{});
Now you can do:
result["2017-05-25T04:00:00.000Z"].forEach(console.log);
How it works:
posts.reduce((obj,event)=>...,{}) //iterate over the posts and pass each as event to the function and also pass an object to be filled
(obj[event.date]=obj[event.date] || [])//return the date array, or create a new one if it doesnt exist
.push(event)//append our event to it

Related

How to get the duplicates objects in an array?

I have an array like this:
var clients=[{"id":1,"name":"john","age":20},
{"id":3,"name":"dean","age":23},
{"id":12,"name":"harry","age":14},
{"id":1,"name":"sam","age":22},
{"id":13,"name":"Bolivia","age":16},
{"id":7,"name":"sabi","age":60},
{"id":7,"name":"sahra","age":40},
{"id":4,"name":"natie","age":53},{"id":7,"name":"many","age":22}]
I want to find the duplicate objects and cluster them like this:
[
{
"id":1,
"clients":[
{"id":1,"name":"john","age":20},
{"id":1,"name":"sam","age":22}
]
},
{
"id":7,
"clients":[
{"id":7,"name":"sabi","age":60},
{"id":7,"name":"sahra","age":40},
{"id":7,"name":"many","age":22}
]
}
]
can I do that with filter() like this:clients.reduce(//code hier)?
reduce() is tailor made for this. When you want to aggregate over an array and get a computed result, you should use reduce().
find() is another array method, which helps in finding an array element based on a condition (here the matching of id property).
var clients=[{"id":1,"name":"john","age":20},
{"id":3,"name":"dean","age":23},
{"id":12,"name":"harry","age":14},
{"id":1,"name":"sam","age":22},
{"id":13,"name":"Bolivia","age":16},
{"id":7,"name":"sabi","age":60},
{"id":7,"name":"sahra","age":40},
{"id":4,"name":"natie","age":53},{"id":7,"name":"many","age":22}]
let ans = clients.reduce((agg,x,index) => {
let findI = agg.find( a =>
a.id === x.id
);
if(findI) findI.clients.push(x);
else {
agg.push({
id : x.id,
clients : [x]
});
}
return agg;
},[]);
console.log(ans);
The simplest solution would be to loop over the clients and check for an existing object with the same id. If yes, push to clients array. Or else, just create one.
var clients = [{ "id": 1, "name": "john", "age": 20 },
{ "id": 3, "name": "dean", "age": 23 },
{ "id": 12, "name": "harry", "age": 14 },
{ "id": 1, "name": "sam", "age": 22 },
{ "id": 13, "name": "olivia", "age": 16 },
{ "id": 7, "name": "sabi", "age": 60 },
{ "id": 7, "name": "sahra", "age": 40 },
{ "id": 4, "name": "natie", "age": 53 }, { "id": 7, "name": "kany", "age": 22 }]
const groups = [];
for (let client of clients) {
const existingGroup = groups.find(group => group.id == client.id)
if (existingGroup)
existingGroup.clients.push(client);
else {
groups.push({ id: client.id, clients: [client] });
}
}
console.log(groups);
You can reassign the original object with the temporary object just used for this, and continue with your business logic, which I believe is the one you are looking for.

How to find data in for every day of week in mongoose node js

Query
const weekGraph = await tmUserSubscriptions.aggregate([
{
$match:{$and:[{subscriptionId: mongoose.Types.ObjectId(subscriptionId)},
{createdAt:{$gte:moment().startOf('isoweek').toDate(),
$lt:moment().endOf('isoweek').toDate()}}
]}
},
{"$project":{
"_id:":1,
"createdAt":{"$dayOfWeek":"$createdAt"},
"subscriptionId":1,
}},
{"$group":{
"_id":"$createdAt",
"count":{$sum:1},
}}
])
Result i get
"data": [
{
"_id": 7,
"count": 1
},
{
"_id": 5,
"count": 2
},
{
"_id": 6,
"count": 1
}
]
expected Result
"data": [
{
"_id": 7,
"count": 1
},
{
"_id": 6,
"count": 2
},
{
"_id": 5,
"count": 1
},
{
"_id": 4,
"count": 0
},{
"_id": 3,
"count": 0
},{
"_id": 2,
"count": 0
}{
"_id": 1,
"count": 0
}
]
So here i want to achieve all data of current week day by day, in my current query if there is no data any of week day then it will not return that day, but as per my expected result i want all day of week data, if there is no data for any of week day then it will return 0, so i want all 7 days data,
here _id is represent day of week
Mongoose/MongoDB will only return the aggregate if the key exists. Otherwise, it will not return you the data (less data to transfer through the connection is always faster). Therefore, you will need to provide your own defaults if the aggregate does not have data for you.
var results = [{ _id: 1, count: 1 }] // assumed from your response
var hasResult = []
for (var result of results) {
hasResult.push(result._id)
}
for (var i = 1; i <= 7; i++) {
if (!hasResult.includes(i)) {
results.push({ _id: i, count: 0 })
}
}
console.log(results)

How to add new value inside array of object by id (not new item)

I'm trying add a new value inside my array by id. I'm not trying add a new item in my array... For this I can use push(), but it add new item not a new value.
I'm trying do it:
My array:
const data =
[
{
"id": 1,
"year":2019,
"value": 2,
},
{
"id": 2,
"year": 2019,
"value": 89,
},
{
"id": 3,
"year": 2019,
"value": 99,
}
]
Inside an especific id I would to add a new value like this:
data.forEach(item => {
if(item.id === 2){
//data inside id 2 -> item: 55
}
})
So my new dataarray looks like this:
const data =
[
{
"id": 1,
"year":2019,
"value": 2,
},
{
"id": 2,
"year": 2019,
"value": 89,
"item": 55
},
{
"id": 3,
"year": 2019,
"value": 99,
}
]
In most of my searches, I found just how to add a new element. But this I know how to do (push()).
So how to add a new value inside specified id?
Just assign the property you want to add:
data.forEach(item => {
if(item.id === 2){
item.item = 55;
}
})
If the IDs are unique, you can use the .find() method:
var el = data.find(item => item.id === 2);
if (el) {
el.item = 55;
}
try
data.find(x=> x.id==2).item=55;
const data =
[
{
"id": 1,
"year":2019,
"value": 2,
},
{
"id": 2,
"year": 2019,
"value": 89,
},
{
"id": 3,
"year": 2019,
"value": 99,
}
]
data.find(x=>x.id==2).item=55;
console.log(data);
You can iterate and assign value based on your criteria
data.map(function(x){
if(x.id == 2){
x.value = 100;
}
})
You can implement method using Array.find to avoid unnecessary iterations:
const array = [
{
"id": 1,
"year":2019,
"value": 2,
},
{
"id": 2,
"year": 2019,
"value": 89,
},
{
"id": 3,
"year": 2019,
"value": 99,
}
];
const changeValue = (array, id, field, value) =>
array.find(el => el.id === id)[field] = value;
changeValue(array, 1, 'year', 9999);
console.log('result: ', array);
You have an array of objects and you want to add a field to one of the objects. So, first, you have to find the object you want to change. Array items can be accessed by index, but you don't know the index. There are several methods to find an item in an array.
var item = data.find(function(d, i){
return item.id === 2; //criteria
});
or in ES6 syntax:
var item = data.find(d=>d.id == 2);
after that, you can change item the way you want.
item.anotherField = 'another value';
As you said, push() adds an item to the array. It doesn't change existing items in the array.
Your code is more or less right there. To set the property of an item, you can do either object.propertyName = ... or object["propertyName"] = ....
With that, you'd simply need to update your example to look like this:
data.forEach(item => {
if(item.id === 2){
item.item = 55; //data inside id 2 -> item: 55
}
})
As a more efficient alternative, consider Array.find(). It won't continue to loop through the array after it finds the id, whereas your forEach will always loop through the array in its entirety.
const data = [ { "id": 1, "year":2019, "value": 2, }, { "id": 2, "year": 2019, "value": 89, }, { "id": 3, "year": 2019, "value": 99, } ];
( data.find(({id})=> id === 2) || {} ).item = 55;
console.log(data);
You'll notice I've followed the .find() with || {}. This is simply so that if an item with id === 2 isn't found, attempting to set the property won't throw an error.

Return all values as an array after the map function

I want to write to the array the value of each sum of all the reports.
month: donate_report.report[0].reports[0].sum
Unfortunately, this function returns an empty array:
month: donate_report.report[0].reports;
const doubles = month.map(function (elem) {
return elem.sum;
});
Could you please tell me what am I doing wrong? thanks in advance
"reports": [
{
"id": 1,
"sum": 5221,
},
{
"id": 2,
"sum": 5421,
}
]
The data structure you provided was not complete or wrong. Considering it as a object you can use map and return the sum property
var a={"reports": [
{
"id": 1,
"sum": 5221,
},
{
"id": 2,
"sum": 5421,
}
]}
const doubles=a.reports.map((e)=>e.sum);
console.log(doubles)

Create JSON with data from database and JavaScript generated

I need to create a calendar view with fullcalendar.io. For some dates, I have a specific price in my database and I retrieve it, but for some dates (without specific prices) I need to put the usual rates in the objects I need to create with JavaScript. Problem is now because I don't know how to make JSON for that.
In short: I need to have a price for every date, but for some dates I get data from database. How do I create such JSON objects in JavaScript?
I have this code:
var db_data = [
{
"id": 5,
"user_id": 1,
"article_id": 5,
"title": "",
"start": "2016-03-25 15:18:46"
},
{
"id": 4,
"user_id": 1,
"article_id": 5,
"price": 55,
"title": "",
"start": "2016-03-15 15:18:46"
},
{
"id": 3,
"user_id": 1,
"article_id": 5,
"price": 35,
"title": "",
"start": "2016-03-07 15:18:46"
},
{
"id": 2,
"user_id": 1,
"article_id": 5,
"price": 22,
"title": "drugi",
"start": "2016-03-05 15:18:46"
},
{
"id": 1,
"user_id": 1,
"article_id": 5,
"price": 44,
"title": "prvi",
"start": "2016-02-04 15:18:46"
}
];
// declare variables
var period_start = new Date('2016-02-02'),
period_end = new Date('2016-03-03'),
current_date = period_start,
array_of_all_dates = [];
// Create a populated array of dates
// Create a populated array of dates
while (current_date.getTime() <= period_end.getTime()) {
array_of_all_dates.push(current_date);
current_date = new Date(+current_date);
current_date.setDate(current_date.getDate() + 1);
}
// Now loop over the array of populated dates and mutate, so something like
array_of_all_dates = array_of_all_dates.map(function (date) {
var found_in_db = db_data.filter(function (db_data) {
return new Date(db_data.start.replace(" ", "T")).getTime() === date.getTime(); // You need to do this comparison better!
});
if (found_in_db.length > 0) {
return found_in_db[0];
}
var new_object = {
title: '',
start: date,
price: '{{$article->price}}'
};
console.log(new_object);
return new_object;
});
console.log('result'+array_of_all_dates);
drawCalendar(array_of_all_dates);
And with this code I get data from database and dates (start) which are not excist in database I create with JavaScript.
But with this function I get this data and I can't create calendar:
I also try with this:
// Now loop over the array of populated dates and mutate, so something like
array_of_all_dates = array_of_all_dates.map(function (date) {
var found_in_db = db_data.filter(function (db_data) {
var db_data_date = new Date(db_data.start.replace(" ", "T"));
return db_data_date.getFullYear() === date.getFullYear() &&
db_data_date.getMonth() === date.getMonth() &&
db_data_date.getDay() === date.getDay();
});
if (found_in_db.length > 0) {
return found_in_db[0];
}
var new_object = {
a_property: 'some_default_value',
start: date
};
console.log(new_object);
return new_object;
});
But currently I get this:
I don't see how this:
new Date(db_data.start.replace(" ", "T")).getTime() === date.getTime()
can ever be true. The dates in db_data have a time set in them "2016-03-15 15:18:46", but the dates you create in array_of_all_dates do not Date('2016-02-02').
Your second date comparison seems to work, but I am unclear what it is you hope to be the result of the:
array_of_all_dates.map( ... );
In some case you return an element from db_data which looks like this:
{ "id": 5", "user_id": 1, "article_id": 5, "title": "", "start": "2016-03-25 15:18:46" }
and if there was no "match" you return an object that looks like this:
{ a_property: 'some_default_value', start: date }
Note that all the original elements of array_of_all_dates are replaced by this operation.
What is it that you want to end up in array_of_all_dates so you can pass it to drawCalendar?

Categories

Resources