For Loop Appending Object Multiple Times in Javascript - javascript

I have the following code.
const timeLabels = [
{ name: "1:00 AM", present: true, label: ["1:00", "2:00"], value: "1:00" },
{ name: "2:00 AM", present: true, label: ["2:00", "3:00"], value: "2:00"},
{ name: "3:00 AM", present: true, label: ["3:00", "4:00"], value: "3:00" },
];
const targetedTimes = [["0:00", "1:00"], ["1:00", "2:00"]]
let actualTime = [];
console.log("getting time");
console.log("start: the actualTime is", actualTime);
for (var j = 0; j < timeLabels.length; j++) {
console.log("x");
var currItem = timeLabels[j];
var label = JSON.stringify(currItem.label);
var adTime = JSON.stringify(targetedTimes);
if (adTime.indexOf(label) >= 0) {
currItem.present = true;
} else {
currItem.present = false;
}
console.log("the current item is", currItem);
actualTime.push(currItem);
console.log("The actual time is", actualTime);
}
On the FIRST iteration, the currItem is
{name: "1:00 AM", present: true, label: Array(2), value: "1:00"}
But the actualTime is
[{name: "1:00 AM", present: true, label: Array(2), value: "1:00"},
{name: "2:00 AM", present: false, label: Array(2), value: "2:00"},
{name: "3:00 AM", present: false, label: Array(2), value: "3:00"}]
Why would the actualTime list have three values when I only append 1 on the first iteration?

What is happening is that the console is printing a reference to the object (becuase arrays are a type of object in javascript), so by the time you print it and read it in the console, each console.log statement is pointing at the same final array, which is why the values is the same each time.
Have a look at this similar StackOverflow question for more insight.
I tried running your script on node and it printed out the array correctly on each iteration, with only one item in the first iteration, so your code is fine.

Related

Remove " " from keys when PHP associative array in parsed through json_encode

I am trying to supply some data to a Javascript Function but right now i am unable to convert it to desired format.
The Correct Format that is Working is below.
const eventsArr = [
{
day: 1,
month: 1,
year: 2023,
events: [
{
title: "asdEvent 1 lorem ipsun dolar sit genfa tersd dsad ",
time: "10:00 AM",
}
],
},
{
day: 13,
month: 11,
year: 2022,
events: [
{
title: "Event 2",
time: "11:00 AM",
},
],
},
];
The format is am being able to produce is the following.
const eventsArr = [
{
"day": "18",
"month": "2",
"year": "2023",
"events": [
{
"title": "Feb 18th Event and Updated From Databae",
"time": "05:10"
}
]
}
The Only difference between two javascript objects/arrays is that my version has "" around the keys and the working format does not have "" around the keys.
My Server Side PHP Code where i am using json_encode
$events = [];
foreach($db_data['CalendarEvent'] as $event)
{
$single_event = array(
'day'=>$event->ce_day,
'month'=>$event->ce_month,
'year'=>$event->ce_year,
'events'=>array(
array(
'title'=> $event->ce_title,
'time'=> $event->ce_time_from,
)
)
);
$events[] = $single_event;
}
$db_data['all_events'] = json_encode($events , JSON_PRETTY_PRINT);
Can somebody help me in this? How can i produce the required format (without "" around the keys in javascript). What i am doing wrong?
Thanks in Advance

pushing a Date into an array always put the same Date, the last element of my array

I'm working with a function that needs to return an array with data, the data of the Dates is always the same but the definition of the dates is not the same, here the dates saved in an array, every date is different but when I try to put this data in other array always return the last date from the array:
const dates=[new Date(startTimestamp), new Date(startTimestamp+ 6.048e+8), new Date(startTimestamp+2*+ 6.048e+8), new Date(startTimestamp+3*+ 6.048e+8)]
for (let index = 0; index < 4; index++) {
const week = weeksData[weekIndex + index];//I have an array of weeks to search for some data
//if that data is not in the array then i want to add a new week with a new Date
if (week !== undefined ) {
newWeeks.push(week);
}
else{
const mockWeek={}
mockWeek.timestamp=dates[index].valueOf();
mockWeek.week= dayjs(dates[index]).format('MMM DD');
console.log(dates[index])
console.log(mockWeek)
newWeeks.push(mockWeek)
}
}
here you can see that the loop has the rights values but, in the end the array doesnt put the desiered value in the final array
What I'm doing wrong ?
The weeks array is like this
Array(17)
0: Week
id: "test-project_1652590800000"
projectId: "test-project"
data:{...}
timestamp: 1652590800000
week: "May 15"
1: Week
id: "test-project_1641196800000"
projectId: "test-project"
data:{...}
timestamp: 1641196800000
week: "Jan 03"
2: Week
id: "test-project_1641801600000"
projectId: "test-project"
data:{...}
timestamp: 1641801600000
week: "Jan 10"
I search in this array by some Date, but if the date donĀ“t exist, thats when I want to add the mockWeek, with the same data,but with a different week and timestamp, there's when the mock week always have the last date from the array, here i don't have the may 8 and may 1 for example, then i want to add a mock week like this
3: Week
id: "test-project_1651381200000"
projectId: "test-project"
data:{...}
timestamp: 1651381200000
week: "May 1"
4: Week
id: "test-project_1651986000000"
projectId: "test-project"
data:{...}
timestamp: 1651986000000
week: "May 8"
But instead I have in both week data the "May 8" and timestamp from "May 8"
This isn't an answer, it's a long comment seeking clarification.
Creating a runnable snippet from the posted code shows it doesn't behave as described. I've added semicolons and fixed the syntax errors. It seems to do what you want (i.e. add missing week objects to the newWeeks array).
You need to post code (preferably as a runnable snippet) that demonstrates the issue. Until then, responses can only be guesses.
let startTimestamp = new Date().setHours(0,0,0,0);
let dates=[new Date(startTimestamp), new Date(startTimestamp+ 6.048e+8), new Date(startTimestamp+2*+ 6.048e+8), new Date(startTimestamp+3*+ 6.048e+8)];
let weekIndex = 5; // Ensure no weeks are found
let newWeeks = [];
let weeksData = [{ // Minimal data in array from OP
0: 'Week',
timestamp: 1652590800000,
week: "May 15"
},{
1: 'Week',
timestamp: 1641196800000,
week: "Jan 03"
},{
2: 'Week',
timestamp: 1641801600000,
week: "Jan 10"
}];
// Loop from OP
for (let index = 0; index < 4; index++) {
let week = weeksData[weekIndex + index];
if (week !== undefined ) {
newWeeks.push(week);
} else {
let mockWeek = {};
mockWeek.timestamp = dates[index].valueOf();
mockWeek.week = dayjs(dates[index]).format('MMM DD');
console.log(dates[index]);
console.log(mockWeek);
newWeeks.push(mockWeek);
}
}
console.log(newWeeks);
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.2/dayjs.min.js"></script>

Get common data from multiple arrays of object that containing a unique id and nested array using javascript es6

I am trying to find the common data from multiple arrays of object that contains a unique id (mongoose object id) and an array of string.
for example:
array1 = [{
_id: "60f027f98b55eb2df1f36c04",
date: "2021-07-15T12:18:12.223Z",
time: "30",
hours: ["8:00 AM", "8:30 AM"]
}]
array2 = [{
_id: "60f027f98b55eb2df1f36c05",
date: "2021-07-15T12:18:12.223Z",
time: "60",
hours: ["7:30 AM", "8:30 AM", "9:30AM"]
}]
array3 = [{
_id: "60f027f98b55eb2df1f36c06",
date: "2021-07-16T12:12:12.223Z",
time: "30",
hours: ["7:00 AM", "8:30 AM"]
}]
The output should have maximum common values in the arrays for maximum common dates and that date should have maximum common hour.
So the sample output should look something like this.
common_data = {
date: "2021-07-15T12:18:12.223Z",
time: "30",
hours: "8:30AM"
}
I looked up at other answers and tried something like this:
merged all the arrays and
let result = merged_slots_array.shift().filter(function(v) {
return merged_slots_array.every(function(a) {
const matchDate = a.date === v.date;
const getMatchTime = a.hours.shift().filter(function(x) {
return v.hours.every(function(t) {
return x.indexOf(t) !== -1;
})
});
return matchDate && getMatchTime
});
});
but getting error merged_slots_array.shift(...).filter is not a function
After concatenating the arrays, finding the max common hour can be done through a filter that only keeps duplicates, then gets sorted. Once we have that, we can query each array to make sure it contains the max hour, then extract the max date and time. My output was slightly different than yours because i filtered for the max time, hour and date
array1 = [{
_id: "60f027f98b55eb2df1f36c04",
date: "2021-07-15T12:18:12.223Z",
time: "30",
hours: ["8:00 AM", "8:30 AM"]
}]
array2 = [{
_id: "60f027f98b55eb2df1f36c05",
date: "2021-07-15T12:18:12.223Z",
time: "60",
hours: ["7:30 AM", "8:30 AM", "9:30AM"]
}]
array3 = [{
_id: "60f027f98b55eb2df1f36c06",
date: "2021-07-16T12:12:12.223Z",
time: "30",
hours: ["7:00 AM", "8:30 AM"]
}]
const getCommon = (arrays) => {
let group = [].concat.apply([], [...arrays])
let hour = group.map(e=>e.hours).flat().filter((e,i,a) => a.indexOf(e) !== i).sort((a,b) => a.localeCompare(b))[0]
let common = group.filter(e=>e.hours.includes(hour))
let time = Math.max(...common.map(e => +e.time))
let date = common.map(e => e.date).sort((a,b) => new Date(b) - new Date(a))[0];
return {date: date, time: time, hours: [hour]}
}
let arg = []
arg.push(array1)
arg.push(array2)
arg.push(array3)
console.log(getCommon(arg))
TS Playground

How to get a new array from an array with nested objects?

I have the below array:
var data = [
{ "id":"id1", "key":"2020-07-15T06:32:44.08Z", "value":["E19","on"] },
{ "id":"id2", "key":"2020-07-15T06:32:44.08Z", "value":["E20","on"] },
{ "id":"id3", "key":"2020-07-15T06:32:44.08Z", "value":["E21","off"] },
{ "id":"id1", "key":"2020-07-15T06:33:44.08Z", "value":["E19","on"] },
{ "id":"id4", "key":"2020-07-15T06:34:44.08Z", "value":["E19","faulty"] },
{ "id":"id5", "key":"2020-07-15T06:35:44.08Z", "value":["E19","on"] }
];
I want this data to be converted to the below form to be used on Google charts:
var expectedData = [
["time","on","off","faulty"],
["06:32:44",2,1,0],
["06:33:44",2,1,0], //here the count is same because E19 is only records for this time which is
//already marked as 'on' in the before time stamp. Hence no change is required.
["06:34:44",1,1,1], //E19 has been changed to 'faulty', hence 'on' is reduced by 1 and 'faulty'
//increased by 1
["06:35:44",2,1,0] //E19 is changed back to 'on' hence 'on' is increased by 1 and 'faulty'
//reduced by 1
];
Can someone please help me with javascript code to sort this data to be used in my React Google charts?
I have written the below code so far:
const data = [
{ "id":"id1", "key":"2020-07-15T06:32:44.08Z", "value":["GigabyteEthernet4/0/19","on"] },
{ "id":"id2", "key":"2020-07-15T06:32:44.08Z", "value":["GigabyteEthernet4/0/20","on"] },
{ "id":"id3", "key":"2020-07-15T06:32:44.08Z", "value":["GigabyteEthernet4/0/21","off"] },
{ "id":"id1", "key":"2020-07-15T06:33:44.08Z", "value":["GigabyteEthernet4/0/19","on"] },
{ "id":"id4", "key":"2020-07-15T06:34:44.08Z", "value":["GigabyteEthernet4/0/19","faulty"] },
{ "id":"id5", "key":"2020-07-15T06:35:44.08Z", "value":["GigabyteEthernet4/0/19","on"] }
];
// var poeObj = new Object();
let t;
var newArray= [];
var newData = data.map((item,el)=>{
t= new Date(item.key);
var poeObj = Object.assign({},el)
poeObj.time= t.toLocaleTimeString();
poeObj.intfName= item.value[0];
poeObj.state= item.value[1];
if(poeObj.intfName)
console.log(poeObj);
return poeObj;
})
console.log(newData)
var newData1 = [
{time: "12:02:44 PM", intfName: "GigabyteEthernet4/0/19", state: "on"},
{time: "12:02:44 PM", intfName: "GigabyteEthernet4/0/20", state: "on"},
{time: "12:02:44 PM", intfName: "GigabyteEthernet4/0/21", state: "off"},
{time: "12:03:44 PM", intfName: "GigabyteEthernet4/0/19", state: "on"},
{time: "12:04:44 PM", intfName: "GigabyteEthernet4/0/19", state: "faulty"},
{time: "12:05:44 PM", intfName: "GigabyteEthernet4/0/19", state: "on"}
]
var uniqueData = newData1.reduce((arr,item)=>{
var newArr = [];
newArr.push(item.time, item.intfName, item.state);
console.log(newArr)
arr.push(newArr)
return arr;
},[])
console.log(uniqueData)
//uniqueData= [
["12:02:44 PM", "GigabyteEthernet4/0/19", "on"],
["12:02:44 PM", "GigabyteEthernet4/0/20", "on"],
["12:02:44 PM", "GigabyteEthernet4/0/21", "off"],
["12:03:44 PM", "GigabyteEthernet4/0/19", "on"],
["12:04:44 PM", "GigabyteEthernet4/0/19", "faulty"],
["12:05:44 PM", "GigabyteEthernet4/0/19", "on"]
];
After all these code, I have got the formatted array as the above 'uniqueData'. But not sure if this is the efficient way. Although, I idn't reach my final expected output which is 'expectedData' mentioned in the begining. Can some one please advise me on this?
You can transform the content of your item in an array by using Array map function.
If I have the following:
var data = [
{ "id":"1", "title":"Lorem ipsum" },
{ "id":"2", "title":"Test title" },
{ "id":"3", "title":"another title" },
];
I can do:
// .map will traverse each item and we pass a function on how we want to deal with new item structure
data.map((item) => {
// I will convert individual item to this format: Array[id, title]
return [item.id, item.title]
})
This will return
[
[1, "Lorem ipsum"],
[2, "Test title"],
[3, "another title"],
]
In your question you have a different item structure in your array ["time","on","off","faulty"]
by getting the output from .map you just append using .splice ["time","on","off","faulty"] from your .map result.
// This will append ["time","on","off","faulty"] in the first index of array
result.splice(0, 0, ["time","on","off","faulty"])
Using reduce is also possible
I can do:
// Reduce also works by merging items, it can take two parameters (function, initial value)
data.reduce((accumulated, currentItem) => {
accumulated.push([currentItem.id, currentItem.title])
}, [["time","on","off","faulty"]])
This will have similar output with .map, the difference is you can put ahead the ["time","on","off","faulty"] in your new array without doing splice.

jQuery Add Array Values

I have a json given below
0 : {car_rental_id: "6007", sharing_schedule: "9:00 AM", booked_cars: '1', woo_order_id: "6421", woo_status: "on-hold" }
1 : {car_rental_id: "6007", sharing_schedule: "9:00 AM", booked_cars: '3', woo_order_id: "6424", woo_status: "pending" }
2 : {car_rental_id: "6007", sharing_schedule: "10:00 AM", booked_cars: '5', woo_order_id: "6427", woo_status: "pending"}
The goal here is to get the total number of booked_cars on a time. So according to this json. I should get
4 bookings for 9:00 AM and 5 bookings for 10:00 AM.
How do I achieve that?
var test = [{
car_rental_id: "6007",
sharing_schedule: "9:00 AM",
woo_order_id: "6421",
woo_status: "on-hold",
booked_cars: '1'
}, {
car_rental_id: "6007",
sharing_schedule: "9:00 AM",
woo_order_id: "6424",
woo_status: "pending",
booked_cars: '3'
}, {
car_rental_id: "6007",
sharing_schedule: "10:00 AM",
woo_order_id: "6427",
woo_status: "pending",
booked_cars: '5'
}];
var carsBookedByTime = test.reduce(function(collection, element){
var bookedCars = parseInt(element.booked_cars);
//initialize total in the collection if it does not exist
if (!collection[element.sharing_schedule]) collection[element.sharing_schedule] = 0;
collection[element.sharing_schedule] += bookedCars;
return collection;
}, {});
console.log(carsBookedByTime);
You could change it to something like that.
var values = window.confirmedBookings.reduce(function(prev, current) {
if(!prev[current.sharing_schedule]) prev[current.sharing_schedule] = 0;
prev[current.sharing_schedule] += Number(current.booked_cars);
return prev;
}, {})
#edit: updated an answer to fit a question.
You appear to be asking for :
window.totalBooked = {};
$.each(window.confirmedBookings, function(index, value) {
console.log(value.booked_cars);
window.totalBooked[value.sharing_schedule] = (window.totalBooked[value.sharing_schedule] || 0) + +value.booked_cars;
});
or, slightly simpler :
window.totalBooked = window.confirmedBookings.reduce(function(obj, value) {
obj[value.sharing_schedule] = (obj[value.sharing_schedule] || 0) + +value.booked_cars;
return obj;
}, {});
DEMO

Categories