Group object values by date - javascript

I'm trying to make an upcoming event on react native, I have this object
const calendatData = [
{
"data": [
{
"id": 25,
"title": "Spotify",
"name": "Family",
"service_id": 1,
"repetition": "Monthly",
"price": "79000",
"upcoming_date": [
"2020-08-07T13:35:44.606Z"
]
},
{
"id": 26,
"title": "Netflix",
"name": "Mobile",
"service_id": 2,
"repetition": "Monthly",
"price": "49000",
"upcoming_date": [
"2020-08-18T13:35:44.600Z",
"2020-08-07T13:35:44.606Z"
]
},
{
"id": 27,
"title": "iTunes",
"name": "Weekly Special",
"service_id": 3,
"repetition": "Weekly",
"price": "22000",
"upcoming_date": [
"2020-08-07T13:35:44.606Z",
"2020-08-14T13:35:44.606Z",
"2020-08-21T13:35:44.606Z",
"2020-08-28T13:35:44.606Z"
]
}
],
"status": "success"
}
]
what I've been trying to do is to extract that object based on the upcoming_date.
the result that I need is like this
upcomingData = [
{
date: '2020-08-07',
title: [
'Spotify',
'Netflix',
'iTunes'
]
},
{
date: '2020-08-18',
title: ['Netflix']
},
{
date: '2020-08-14',
title: ['iTuunes']
},
{
date: '2020-08-21',
title: ['iTuunes']
},
{
date: '2020-08-28',
title: ['iTuunes']
}
]
On the same date, if there are multiple titles, it should be grouped under the same date in the object.
instead what I got was this object
upcomingData = [
{
title: [
"Spotify",
"Netflix",
"iTunes",
],
date : [
"2020-08-29",
"2020-08-07",
"2020-08-18",
"2020-08-07",
"2020-08-07",
"2020-08-14",
"2020-08-21",
"2020-08-28",
]
}
]
I am new to this, and I'm aware that this is mostly about javascript knowledge, any help would be appreciated.
thanks

The ideas are:
First, iterate your object by Array.prototype.map() and set a unique map key from the converted date.
Then push the title to every map's key.
Actually your final map(here is myMap) will be your expected upcomingData. To output as your expected object, you can make it in your own way.
const calendarData = [{ "data": [{ "id": 25, "title": "Spotify", "name": "Family", "service_id": 1, "repetition": "Monthly", "price": "79000", "upcoming_date": ["2020-08-07T13:35:44.606Z"] }, { "id": 26, "title": "Netflix", "name": "Mobile", "service_id": 2, "repetition": "Monthly", "price": "49000", "upcoming_date": ["2020-08-18T13:35:44.600Z", "2020-08-07T13:35:44.606Z"] }, { "id": 27, "title": "iTunes", "name": "Weekly Special", "service_id": 3, "repetition": "Weekly", "price": "22000", "upcoming_date": ["2020-08-07T13:35:44.606Z", "2020-08-14T13:35:44.606Z", "2020-08-21T13:35:44.606Z", "2020-08-28T13:35:44.606Z"] }], "status": "success" }];
var myMap = new Map();
calendarData[0].data.map(element => {
var dates = [];
element.upcoming_date.map(date => {
var upcoming_date = date.slice(0,10);
if (!myMap.get(upcoming_date)) {
myMap.set(upcoming_date, []);
}
dates.push(upcoming_date);
});
var len = dates.length;
for (let i = 0; i < len; i++) {
myMap.get(dates[i]).push(element.title);
}
});
var upcomingData = [];
for (const entry of myMap.entries()) {
var obj = {};
obj["date"] = entry[0];
obj["title"] = entry[1];
upcomingData.push(obj);
}
console.log(upcomingData);

You may
traverse your source array with Array.prototype.reduce() building up the Map where trimmed portion of your date string is used as a key and the object of desired format as a value
extract Map values, using Map.prototype.values() into resulting array
Following is a quick live demo:
const src = [{"data":[{"id":25,"title":"Spotify","name":"Family","service_id":1,"repetition":"Monthly","price":"79000","upcoming_date":["2020-08-07T13:35:44.606Z"]},{"id":26,"title":"Netflix","name":"Mobile","service_id":2,"repetition":"Monthly","price":"49000","upcoming_date":["2020-08-18T13:35:44.600Z","2020-08-07T13:35:44.606Z"]},{"id":27,"title":"iTunes","name":"Weekly Special","service_id":3,"repetition":"Weekly","price":"22000","upcoming_date":["2020-08-07T13:35:44.606Z","2020-08-14T13:35:44.606Z","2020-08-21T13:35:44.606Z","2020-08-28T13:35:44.606Z"]}],"status":"success"}],
result = [...src[0].data
.reduce((r,{upcoming_date, title}) => (
upcoming_date.forEach((s,_,__,date=s.slice(0,10)) =>
r.set(
date,
{date, title: [...(r.get(date)?.title||[]), title]}
)),r),
new Map())
.values()
]
console.log(result)
.as-console-wrapper{min-height:100%;}

Related

how to convert array into new array of parent children

I have restaurant data array , I should make another array by grouping items by category that belongs to , I should convert this array :
[
{
"category": {
"title": "Appetizers",
},
"id": 1,
"price": "10",
"title": "Spinach Artichoke Dip",
},
{
"category": {
"title": "Appetizers",
},
"id": 2,
"price": "10",
"title": "Hummus",
},
{
"category": {
"title": "Salads",
},
"id": 3,
"price": "7",
"title": "Greek",
},
{
"category": {
"title": "Salads",
},
"id": 4,
"price": "9",
"title": "Beyn",
}
]
into a new array that should be as final result like this:
[{
"category": "Appetizers",
"items" : ["Spinach Artichoke Dip","Hummus"]
},
{
"category" : "Salads",
"items" :["Greek", "Beyn"]
}
]
I can't find how to do it could you please help
Lets say that your data is a constant called data
So you can do this:
const data = [
{
"category": {
"title": "Appetizers",
},
"id": 1,
"price": "10",
"title": "Spinach Artichoke Dip",
},
{
"category": {
"title": "Appetizers",
},
"id": 2,
"price": "10",
"title": "Hummus",
},
{
"category": {
"title": "Salads",
},
"id": 3,
"price": "7",
"title": "Greek",
},
{
"category": {
"title": "Salads",
},
"id": 4,
"price": "9",
"title": "Beyn",
}
];
const result = [];
data.forEach((item) => {
const category = item.category.title;
const title = item.title;
let foundCategory = result.find((c) => c.category === category);
if (foundCategory) {
foundCategory.items.push(title);
} else {
result.push({ category, items: [title] });
}
});
console.log(result);
Now your desired result will be stored in result
happy coding
const itemsToCategories = (itemsArr) => {
const store = {};
itemsArr.forEach(item => {
const categoryTitle = item.category.title;
if (!store[categoryTitle]) store[categoryTitle] = [];
store[categoryTitle].push(item.title);
});
return Object.entries(store).map(([category, items]) => ({ category, items}));
};
This solution should be a bit faster than the accepted answer for large data sets. The main difference is the use of an object (store) instead of an array, so lookups by the category title are more efficient. Then we build an array from that object at the end.
This does have more overhead than the accepted solution above, so for smaller data sets, this ends up being slower in comparison.

Is there any way to filter objects from array of objects that should include all selected values in javascript

Here i have skills array and employees array and i am trying to get the employees that includes all the skills that are included in skills array using reduce, filter or find method. I am trying to stored the filtered employees in filteredItems but got stuck in it.
filteredItems = Skills?.length>0 ?
Employees?.filter((item) => {
return item.Skills.find((ele) => {
return Skills.find((el) => {
if(el.value === ele.id){
return ele
}
})
})
}) : []
Below are the arrays mentioned.
Skills Array
[
{
"value": 6,
"label": "Marketing"
},
{
"value": 20,
"label": "Golang"
}
]
Employees Array
[
{
"name": "Hassan",
"id": 56,
"Skills": [
{
"id": 20,
"name": "Golang",
},
],
},
{
"name": "Haroon",
"id": 95,
"Skills": [
{
"id": 6,
"name": "Marketing",
},
{
"id": 20,
"name": "Golang",
},
],
},
]
For example, in above scenario of arrays it should return employee of id of 95 not return employee of id 56 because it includes skills but not all that are mention in skills array.
I found it easier to first encapsulate an array of skill IDs to search for.
let skillIds = Skills.map(s => s.value);
Then I filtered and compared the end result to the length of the skill Ids array:
let filteredItems = Skills?.length > 0 ?
Employees?.filter(item => item.Skills.filter( s =>
skillIds.includes(s.id)).length==skillIds.length): []
let Skills = [{
"value": 6,
"label": "Marketing"
}, {
"value": 20,
"label": "Golang"
}]
let Employees = [{
"name": "Hassan",
"id": 56,
"Skills": [{
"id": 20,
"name": "Golang",
}],
}, {
"name": "Haroon",
"id": 95,
"Skills": [{
"id": 6,
"name": "Marketing",
},
{
"id": 20,
"name": "Golang",
},
],
}, ]
let skillIds = Skills.map(s => s.value);
let filteredItems = Skills?.length > 0 ?
Employees?.filter(item => item.Skills.filter( s => skillIds.includes(s.id)).length==skillIds.length): []
console.log(filteredItems)
You could create another property in the employees array.. call it "QUalified". Default it to true, then set it to false when the employee doesn't have a skill in the skills array.
let arSkills = [
{
"value": 6,
"label": "Marketing"
},
{
"value": 20,
"label": "Golang"
}
];
let arEmp = [
{
"name": "Hassan",
"id": 56,
"Skills": [
{
"id": 20,
"name": "Golang",
},
],
},
{
"name": "Haroon",
"id": 95,
"Skills": [
{
"id": 6,
"name": "Marketing",
},
{
"id": 20,
"name": "Golang",
},
],
},
];
arEmp.forEach(ele =>{
ele.Qualified = true;
let arTmp = [];
for(let {id} of ele.Skills)
arTmp.push(id)
for(let {value} of arSkills)
if(!arTmp.includes(value))
ele.Qualified = false
});
let arQual = arEmp.filter((ele) =>{
return ele.Qualified
});
console.log(arQual);

Remove the first bracket from nested array

I have an array as follow:
let data =[
[
{
"Id": "110d611c-54e4-4593-a835-def0f34ed882",
"duration": 30,
"name": "burger",
"price": 10,
}
],
[
{
"Id": "edc241e9-5caf-4f0b-b6ea-6cf5fc57d260",
"duration": 10,
"name": "Cake",
"price": 5,
}
]
]
I am trying to remove the first bracket to be like this:
let data =
[
{
"Id": "110d611c-54e4-4593-a835-def0f34ed882",
"duration": 30,
"name": "burger",
"price": 10,
}
],
[
{
"Id": "edc241e9-5caf-4f0b-b6ea-6cf5fc57d260",
"duration": 10,
"name": "Cake",
"price": 5,
}
]
I have trying many solutions, the most common one i have tried is using this way:
let newData = data[0]
but the result always giving me the first nested array something like this:
[
{
"Id": "110d611c-54e4-4593-a835-def0f34ed882",
"duration": 30,
"name": "burger",
"price": 10
}
]
I tried to convert it to string using JSON.stringify() then remove the bracket by doing
JSON.stringify(data).substring(1, JSON.stringify(data).length - 1);
But then when i parse it i get this error:
SyntaxError: JSON Parse error: Unable to parse JSON string
I am really stuck on what the best way to accomplish it.
thanks in advance.
You want the first element of each nested array, not the first element of the outer array. So use map().
let data = [
[{
"Id": "110d611c-54e4-4593-a835-def0f34ed882",
"duration": 30,
"name": "burger",
"price": 10,
}],
[{
"Id": "edc241e9-5caf-4f0b-b6ea-6cf5fc57d260",
"duration": 10,
"name": "Cake",
"price": 5,
}]
];
let newData = data.map(el => el[0]);
console.log(newData);
Removing the external bracket will result in an invalid javascript object.
To obtain a single array with all the objects you can use flatMap
data.flatMap(x => x)
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap
The result that you want is not valid, instead you can get array of object using flat as:
data.flat()
let data = [
[
{
Id: "110d611c-54e4-4593-a835-def0f34ed882",
duration: 30,
name: "burger",
price: 10,
},
],
[
{
Id: "edc241e9-5caf-4f0b-b6ea-6cf5fc57d260",
duration: 10,
name: "Cake",
price: 5,
},
],
];
const result = data.flat();
console.log(result);

How can i make json file like this when i input

How can i make the cart_items like my expetation.. just it no more.. my problem just it :D
i just wanna make my cart_items like this.. hope you are can help me thanks. did I make the wrong method? and one more thing, i wanna make the qty inside the cart_items
this is my expectation
"cart": [
{
"id": 1,
"date": "12/10/2020",
"store": {
"id": 1,
"name": "Dirumah Aja",
"promo": 1
},
"cart_items": [
{
"id": 1,
"product": {
"id": 1,
"name": "Bakso Urat",
"price": 10000,
"promo": {
"nama": "promo"
}
},
"qty": 5
}
]
}
]
and this is what I got
"cart": [
{
"cart_items": {
"name": "Steak Sapi Impor",
"price": "38000",
"stock": "4",
"image": "https://firebasestorage.googleapis.com/v0/b/francise-fb70a.appspot.com/o/steak.jpg?alt=media&token=46e0d769-96d3-440f-8edb-5fce2481ace0",
"promo": 3,
"id": 8,
"qty": 1
},
"store": {
"name": "Amanda Foods Store",
"email": "amanda#food.com",
"store_image": "https://firebasestorage.googleapis.com/v0/b/francise-fb70a.appspot.com/o/full_hd_retina.jpeg?alt=media&token=3e602e86-661b-48ee-9e9c-af9f94a170d1",
"product": [
5,
7,
8,
2
],
"store_promo": 1,
"location": {
"street_name": "Jl. Kebon Gedang II B",
"province": "Jawa Barat",
"city": "Bandung",
"post_code": "40285"
},
"id": 1
},
"date_order": "Nov 03 2020 08:48:03",
"id": 2
}
]
This is my data
data() {
return {
promo_id: [],
promo_partner: [],
products: {},
qty: 1,
cart_items: [
{}
]
};
and this is my method
addToCart() {
const date = (new Date()).toString().split(' ').splice(1,4).join(' ')
this.products.cart_items = this.product;
this.products.cart_items.qty = this.qty;
this.products.store = this.partner;
this.products.date_order = date;
console.log(this.cart_items)
axios
.post("http://localhost:3000/cart/", this.products)
.then(() => {
swal("Belanja Berhasil!", {
icon: "success",
});
})
.catch((error) => console.log(error));
}
}
You need to use .push() to add items to an array. You're replacing the array with this.product.
if (!this.products.cart_items) { // initialize cart_items if necessary
this.products.cart_items = [];
}
this.products.cart_items.push({id: this.product.id, product: this.product, qty: this.qty});

How to groupBy in multi arrays using lodash

I want to group By sub-work in array
Here is my array I want to group By sub-work
result = [
{
"date": "10-07-2019",
"data": [
{
"data_id": "20",
"work": "work_1",
"sub-work": "sub_work1",
"sub-data": [
{
"id": 7,
"title": 'subdata-1',
}
]
}
]
},
{
"date": "12-07-2019",
"data": [
{
"data_id": "20",
"work": "work_1",
"sub-work": "sub_work1",
"sub-data": [
{
"id": 7,
"title": 'subdata-1',
}
]
}
]
},
]
Here is what I try
result = _(result)
.map(function(items, data) {
_.groupBy(items.data, function({ sub_work }) {
return sub_work;
});
})
.value();
first I map result into data then I try to groupby but It's return null
Update
I want my output look like this
[
{
"date": "10-07-2019",
sub-work: [{
sub-work : "sub_work1",
sub-data[
{
"id": 7,
"title": 'subdata-1',
}
]
}]
}
]
...........................
It would be better if you could provide your expected result.
Here's what I could infer:
_(result)
.map(function(obj) { // Convert into a 2D array.
return obj.data.map(e => Object.assign(e, {date: obj.date}));
})
.flatten() // We have an array of objects now.
.groupBy('sub-work') // We can call groupBy().
.value();
Here's what you get:
{
"sub_work1": [{
"data_id": "20",
"work": "work_1",
"sub-work": "sub_work1",
"sub-data": [{
"id": 7,
"title": "subdata-1"
}],
"date": "10-07-2019"
}, {
"data_id": "20",
"work": "work_1",
"sub-work": "sub_work1",
"sub-data": [{
"id": 7,
"title": "subdata-1"
}],
"date": "12-07-2019"
}]
}

Categories

Resources