React Native SectionList Split Dates - javascript

I need to reformat my object of dates and I have an array of dates in such format:
Object {
"FREETIME": "2021-04-19 11:30:00",
},
Object {
"FREETIME": "2021-04-19 12:00:00",
},
Object {
"FREETIME": "2021-04-20 12:30:00",
},
Object {
"FREETIME": "2021-04-21 12:50:00",
},
and I would want to render them in section list like this:
const DATA = [
{
title: "2021-04-19",
data: ["11:30:00", "12:00:00"]
},
{
title: "2021-04-20",
data: ["12:30:00"]
},
{
title: "2021-04-21",
data: ["12:50:00"]
},
];
so what I do is first split the array of FREETIME by days and times:
const dates = data.map((item) => item.FREETIME.split(" "));
then I get unique days for section header of SectionList:
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
const days = dates.map((item) => item[0]).filter(onlyUnique);
and then I try to construct new object DATA with days and corresponding times but fail at mapping the times correctly:
const DATA = days.map((dayHeader) => ({
title: dayHeader,
data: //don't know how to map it properly here
}));
What am I doing it wrong or is there another approach to this?

Below is one method of doing the job with Array.prototype.reduce
const arrayOfObjectDates = [
{
"FREETIME": "2021-04-19 11:30:00",
},
{
"FREETIME": "2021-04-19 12:00:00",
},
{
"FREETIME": "2021-04-20 12:30:00",
},
{
"FREETIME": "2021-04-21 12:50:00",
}
];
const DATA = arrayOfObjectDates.reduce((op, { FREETIME }) => {
var [date, time] = FREETIME.split(" "), { result, index } = op;
if (index.hasOwnProperty(date)) {
result[index[date]].data.push(time);
} else {
index[date] = result.length;
result.push({ title: date, data: [time] });
}
return op;
}, { result: [], index: {} }).result;
console.log(DATA)

Related

How do I append a value to an array in a JavaScript object while mapping through the object its contained in?

I have a JavaScript object of the following structure:
results = [
{
date: ... // holds a string representing a date
timeslots: [
{
slotsAvailable: ... // holds an int
time: ... // holds a string representing time
},
{
slotsAvailable: ...
time: ...
}
]
},
{
date: ...
timeslots: [
{
slotsAvailable: ...
time: ...
},
{
slotsAvailable: ...
time: ...
}
]
},
{
date: ...
timeslots: [
{
slotsAvailable: ...
time: ...
},
{
slotsAvailable: ...
time: ...
}
]
}
]
The object starts off empty and I fill it through the following code:
"timeslots": [
{
"slotsAvailable": 1,
"time": "2022-02-11T14:00:00-0500"
},
{
"slotsAvailable": 1,
"time": "2022-02-13T13:40:00-0500"
},
{
"slotsAvailable": 1,
"time": "2022-02-15T17:40:00-0500"
},
{
"slotsAvailable": 1,
"time": "2022-02-15T18:20:00-0500"
},
{
"slotsAvailable": 1,
"time": "2022-02-16T14:00:00-0500"
},
{
"slotsAvailable": 1,
"time": "2022-02-16T14:20:00-0500"
},
{
"slotsAvailable": 1,
"time": "2022-02-17T21:40:00-0500"
}
]
var results = []
let date = new Date(timeslots[0].time)
for(let i = 0; i < 8; i++) {
results = [...results, {date: new Date(date), timeslots: []}] // Date function called b/c otherwise value is passed by reference
date.setDate(date.getDate() + 1)
}
console.log(results)
for(const i in timeslots) {
let slot = timeslots[i]
results.map(result => {
return result.date.getDate() === new Date(slot.time).getDate()
? {...result, timeslots: [...result.timeslots, slot]} // this line doesn't work
: result
})
}
console.log(results)
The results object correctly populates with 8 dates in the first loop, but after the second loop, all of the timeslots arrays are still empty. The intended result is that the final object contains an array of dates where each timeslot is placed in the object corresponding to its date.
I believe the error is with the line in the second loop where I spread in the existing array and append a new value to the array, but I'm not sure how to fix this.
Suggestions?
Is this how you expect your output to be?
const timeslots= [{"slotsAvailable": 1,"time": "2022-02-11T14:00:00-0500"},{"slotsAvailable": 1,"time": "2022-02-13T13:40:00-0500"},{"slotsAvailable": 1,"time": "2022-02-15T17:40:00-0500"},{"slotsAvailable": 1,"time": "2022-02-15T18:20:00-0500"},{"slotsAvailable": 1,"time": "2022-02-16T14:00:00-0500"},{"slotsAvailable": 1,"time": "2022-02-16T14:20:00-0500"},{"slotsAvailable": 1,"time": "2022-02-17T21:40:00-0500"}]
const results = timeslots.reduce((acc, curr) => {
const date = curr.time.split('T')[0];
const time = curr.time.split('T')[1];
const dateTime = date + ' ' + time;
const dateTimeObject = new Date(dateTime);
const dateString = dateTimeObject.toDateString();
const timeString = dateTimeObject.toLocaleTimeString();
const timeObject = {
slotsAvailable: curr.slotsAvailable,
time: timeString,
};
if (acc.length === 0) {
acc.push({
date: dateString,
timeslots: [timeObject],
});
} else {
const lastIndex = acc.length - 1;
const lastDate = acc[lastIndex].date;
if (lastDate === dateString) {
acc[lastIndex].timeslots.push(timeObject);
} else {
acc.push({
date: dateString,
timeslots: [timeObject],
});
}
}
return acc;
}, []);
console.log(JSON.stringify(results, null, 2));
.as-console-wrapper{max-height:100% !important; top:0px}

JavaScript Array attribute change

I have an array like this.
let arr = [
{
"ABBRIVATION":"ISB",
"name":"ISLAMABAD",
},
{
"ABBRIVATION":"RAW",
"name":"PINDI",
},
{
"ABBRIVATION":"SWB",
"name":"SWABI",
},
{
"ABBRIVATION":"AQ",
"name":"AQEEL",
},
]
I want to change it to like this
let me explain it a little. I want to assign the abbreviation directly to the name and the iterate through that array
let outout = [
{
"ISB":"ISLAMABAD"
},
{
"RAW":"ISLAMABAD"
},
{
"SWB":"SWABI"
},
{
"AQ":"AQEEL"
},
]
that is what I tried
let k = arr.map((item) => {
return item.ABB = item.name
})
console.log(k)
and here is the output
[ 'ISLAMABAD', 'PINDI', 'SWABI', 'AQEEL' ]
Here you go, use array map, simples
let arr = [
{
"ABBRIVATION":"ISB",
"name":"ISLAMABAD",
},
{
"ABBRIVATION":"RAW",
"name":"PINDI",
},
{
"ABBRIVATION":"SWB",
"name":"SWABI",
},
{
"ABBRIVATION":"AQ",
"name":"AQEEL",
},
]
let outout = arr.map(({ABBRIVATION, name}) => ({[ABBRIVATION]: name}));
console.log(outout);
Nothing more than a simple Array.prototype.map() needed.
let arr = [
{
ABBRIVATION: "ISB",
name: "ISLAMABAD",
},
{
ABBRIVATION: "RAW",
name: "PINDI",
},
{
ABBRIVATION: "SWB",
name: "SWABI",
},
{
ABBRIVATION: "AQ",
name: "AQEEL",
},
];
const result = arr.map(e => ({ [e.ABBRIVATION]: e.name }));
console.log(result);
map over the array of objects (map returns a new array) and assign the name to a new key defined by the abbreviation.
You code works the way it does because item.ABB is undefined, but you're also assigning item.name to it which does get returned, so you just get an array of names returned.
const arr=[{ABBRIVATION:"ISB",name:"ISLAMABAD"},{ABBRIVATION:"RAW",name:"PINDI"},{ABBRIVATION:"SWB",name:"SWABI"},{ABBRIVATION:"AQ",name:"AQEEL"}];
const out = arr.map(obj => {
return { [obj.ABBRIVATION]: obj.name };
});
console.log(out);
Hi I have seen people answer, but most of them use the map function, I provide some other solutions, hoping to expand the thinking
Use forEach function
const datas = [
{
"ABBRIVATION":"ISB",
"name":"ISLAMABAD",
},
{
"ABBRIVATION":"RAW",
"name":"PINDI",
},
{
"ABBRIVATION":"SWB",
"name":"SWABI",
},
{
"ABBRIVATION":"AQ",
"name":"AQEEL",
}
];
datas.forEach((obj, i, arr) => {
const{'ABBRIVATION':k, 'name':v} = obj;
arr[i] = {[k]:v};
});
console.log(datas);
Use flatMap function
const datas = [
{
"ABBRIVATION":"ISB",
"name":"ISLAMABAD",
},
{
"ABBRIVATION":"RAW",
"name":"PINDI",
},
{
"ABBRIVATION":"SWB",
"name":"SWABI",
},
{
"ABBRIVATION":"AQ",
"name":"AQEEL",
}
];
const result = datas.flatMap(obj => {
const {'ABBRIVATION':k, 'name':v} = obj;
return {[k]:v};
});
console.log(result);
this is how you suppose to do it.
arr.reduce((d, c)=>([...d, {[c.ABBRIVATION]: c.name}]),[])
let arr = [
{
"ABBRIVATION":"ISB",
"name":"ISLAMABAD",
},
{
"ABBRIVATION":"RAW",
"name":"PINDI",
},
{
"ABBRIVATION":"SWB",
"name":"SWABI",
},
{
"ABBRIVATION":"AQ",
"name":"AQEEL",
},
]
console.log(arr.reduce((data, current)=>([...data, {[current.ABBRIVATION]: current.name}]),[]))

How to filter/reduce the data based on the latest date

data = {
start: 1,
data: [
{
name: 'Juan',
date: '2020-01-19
},
{
name: 'Carlo',
date: '2020-03-01
},
{
name: 'Dela',
date: '2020-03-01
},
{
name: 'Cruz',
date: '2021-04-01
}
],
totalRecords: 19
}
What I'm trying to do filter the data to the latest date which is 2020-04-01.
What I tried is like this:
response['data']['data'] = response['data']['data'].filter(item => {
return item['date'] > '2020-04-01';
});
But it doesn't work.
Expected output should be like this
data = {
start: 1,
data: [
{
name: 'Cruz',
date: '2021-04-01
}
],
totalRecords: 19
}
You can use sort and then take the first entry in the array to get the item with the latest date.
data.data.sort((a, b) => new Date(b.date) - new Date(a.date))[0];
Other answers exist some problems (in terms of performance, expected output).
You shouldn't use sort because time complexity will take at least O(nlogn).
Using filter will return more than one lastItem
==> So you can use Array#reduce (with time complexity is just O(n)) like this.
const comparedDate = new Date('2020-04-01')
const response = {
start: 1,
data:[{name:'Juan',date:'2020-01-19'},{name:'Carlo',date:'2020-03-01'},{name:'Dela',date:'2020-03-01'},{name:'Cruz',date:'2021-04-01'}],
totalRecords:19};
const lastData = response.data.reduce((acc, curr) => {
if(new Date(curr.date) > comparedDate)
acc = curr;
return acc;
}, response.data[0]);
console.log(lastData);
In case that you want to result in multiple items <= 2020-04-01, you can do like this
const comparedDate = new Date('2020-04-01')
const response = {
start: 1,
data:[{name:'Juan',date:'2020-01-19'},{name:'Carlo',date:'2020-03-01'},{name:'Dela',date:'2020-03-01'},{name:'Cruz',date:'2021-04-01'}],
totalRecords:19};
response.data = response.data.reduce((acc, curr) => {
if(new Date(curr.date) >= comparedDate)
acc.push(curr);
return acc;
}, []);
console.log(response);
You need to convert the date strings into Date objects.
const checkDate = new Date('2020-04-01')
const response = {
start: 1,
data: [
{
name: 'Juan',
date: '2020-01-19'
},
{
name: 'Carlo',
date: '2020-03-01'
},
{
name: 'Dela',
date: '2020-03-01'
},
{
name: 'Cruz',
date: '2021-04-01'
}
],
totalRecords: 19
}
response.data = response
.data
.filter(({date}) => new Date(date) > checkDate)
console.log(response)

How can I merge object values if they have the same key?

I have an Array full of transactions and I want to divide it by day. It will be an array of date that is and array of transations. It may be a little messy but I want to return this structure.
What I tried to do returns me the structure I want, but I don't know how to merge duplicated key values.
This is the array
const transactions = [
{
name: "Salário",
receiveDate: "2020-05-12T00:00:00.000Z",
value: "1000",
},
{
name: "Pagamento ",
receiveDate: "2020-05-12T00:00:00.000Z",
value: "2350",
},
{
name: "Passagem no VEM",
paidDate: "2020-05-02T00:00:00.000Z",
value: "130",
},
{
name: "Almoço",
paidDate: "2020-05-08T00:00:00.000Z",
value: "50",
},
];
This is what I already tried by now
const days = [];
const finalArray = [];
for (let i = 0; i < transactions.length; i++) {
transactions[i].day = transactions[i].receiveDate || transactions[i].paidDate;
days.push(transactions[i].day);
}
const datesToMatch = [...new Set(days)].map((date) => {
return { [date]: null };
});
transactions.map((transaction) => {
datesToMatch.map((dayObject) => {
const day = Object.keys(dayObject).toString();
if (day === transaction.day) {
finalArray.push({ [day]: [transaction] });
}
});
});
The output
[ { '2020-05-12T00:00:00.000Z': [ [Object] ] },
{ '2020-05-12T00:00:00.000Z': [ [Object] ] },
{ '2020-05-02T00:00:00.000Z': [ [Object] ] },
{ '2020-05-08T00:00:00.000Z': [ [Object] ] } ]
Expected output
[ { '2020-05-12T00:00:00.000Z': [ [Object, Object] ] },
{ '2020-05-02T00:00:00.000Z': [ [Object] ] },
{ '2020-05-08T00:00:00.000Z': [ [Object] ] } ]
Thanks!
Explanation:
dates : extract dates from both fields
uniqueDates : build a Set and convert it into an array so it only has uniqueDates
dateToTransactions : map every unique date to an object with one key (itself) and filter every transaction that is equal to it.
const transactions = [{
name: "Salário",
receiveDate: "2020-05-12T00:00:00.000Z",
value: "1000",
},
{
name: "Pagamento ",
receiveDate: "2020-05-12T00:00:00.000Z",
value: "2350",
},
{
name: "Passagem no VEM",
paidDate: "2020-05-02T00:00:00.000Z",
value: "130",
},
{
name: "Almoço",
paidDate: "2020-05-08T00:00:00.000Z",
value: "50",
},
];
const dates = transactions.map(x => {
const received = x.receiveDate || [];
const paid = x.paidDate || [];
return received + paid;
});
const uniqueDates = [...new Set(dates)];
const dateToTransactions =
uniqueDates.map(
date => {
sameDate = transactions.filter(x => x.receiveDate === date || x.paidDate == date);
return {[date]: sameDate};
});
console.log(dateToTransactions);
I would do something like this:
const days = [];
for (let i = 0; i < transactions.length; i++) {
transactions[i].day = transactions[i].receiveDate || transactions[i].paidDate;
days.push(transactions[i].day);
}
const result = new Map();
days.forEach((day) => {
result.set(day, [])
});
transactions.forEach((transaction) => {
let r = result.get(transaction.day);
r.push(transaction);
result.set(transaction.day, r);
});
Then, in the result map you have a list of the transactions that were made for each day.
This will give the result you expect
const days = {};
const finalArray = transactions.forEach((transaction) => {
let date = (transaction.receiveDate || transaction.paidDate)
if (!days[date]) { days[date] = [transaction]}
else {days[date].push(transaction)}
});
console.log(days);

Group JSON array by key value

Please help to combine object keys values from json arrays by key.
const input=[{
"Date":"04/10/2019",
"Time":"15:35",
"Title":"Flight -\u00a0Group C",
"Description":"Arrival 19:40"
},
{
"Date":"04/10/2019",
"Time":"Evening",
"Title":"Welcome drinks",
"Description":"In the bar at\u00a0"
},
{
"Date":"05/10/2019",
"Time":"Morning",
"Title":"Breakfast",
"Description":"At leisure"
},
{
"Date":"05/10/2019",
"Time":"10:00",
"Title":"Something Else",
"Description":"At leisure"
}];
console.log(
Object.values(input.reduce((a, { Date }) => {
if (!a[Date]) a[Date] = { Date, activities: [] };
a[Date].activities.push();
return a;
}, {}))
);
I need a combined object keys values in javascript in the following way:
[
{
"date":"04/10/2019",
"activities":[
{
"Time":"15:35",
"Title":"Flight -\u00a0Group C",
"Description":"Arrival 19:40"
},
{
"Time":"Evening",
"Title":"Welcome drinks",
"Description":"In the bar at\u00a0"
}
]
},
{
"date":"05/10/2019",
"activities":[
{
"Time":"Morning",
"Title":"Breakfast",
"Description":"At leisure"
}
]
}
]
I am trying to get the result with my code but 'activities' are null...
I would highly appreciate your help.
Thank you in advance
If you are using parameter destructuring you could use ... rest param to get other properties after you take out the date.
const input=[{"Date":"04/10/2019","Time":"15:35","Title":"Flight - Group C","Description":"Arrival 19:40"},{"Date":"04/10/2019","Time":"Evening","Title":"Welcome drinks","Description":"In the bar at "},{"Date":"05/10/2019","Time":"Morning","Title":"Breakfast","Description":"At leisure"},{"Date":"05/10/2019","Time":"10:00","Title":"Something Else","Description":"At leisure"}]
const object = input.reduce((r, { Date: date, ...rest}) => {
if(!r[date]) r[date] = {date, activities: [rest]}
else r[date].activities.push(rest)
return r
}, {})
const result = Object.values(object)
console.log(result)

Categories

Resources