Getting key position in JSON and modify - javascript

How can I know if in a JSON exists "xxx" key? I need these JSONs to be formatted:
let beforeOne = {
"id": "123",
"aDate": {
"$date": "2022-06-24T00:00:00Z"
}
}
let beforeTwo = {
"id": "123",
"firstDate": {
"$date": "2022-06-24T00:00:00Z"
},
"day": {
"today": {
"$date": "2022-06-24T00:00:00Z"
},
"tomorrow": {
"$date": "2022-06-24T00:00:00Z"
}
}
}
to:
let afterOne = {
"id": "123",
"aDate": new Date("2022-06-24T00:00:00Z")
}
let afterTwo = {
"id": "123",
"firstDate": new Date("2022-06-24T00:00:00Z"),
"day": {
"today": new Date("2022-06-24T00:00:00Z"),
"tomorrow": new Date("2022-06-24T00:00:00Z")
}
}
So basically, I need to find everywhere where "$date" is present, remove it and give the parentKey the value from parentKey.$date with the new Date() constructor. How could I do that? Thanks in advance!

You can use a recursive function for this. Each time you see an object that has a $date key, perform the new Date transformation and return this to the caller:
function transformDates(obj) {
return Object(obj) !== obj ? obj // Primitive
// When it has $date:
: obj.hasOwnProperty("$date") ? new Date(obj.$date)
// Recursion
: Object.fromEntries(
Object.entries(obj).map(([k, v]) => [k, transformDates(v)])
);
}
let beforeOne = {"id": "123","aDate": {"$date": "2022-06-24T00:00:00Z"}}
console.log(transformDates(beforeOne));
let beforeTwo = {"id": "123","firstDate": {"$date": "2022-06-24T00:00:00Z"},"day": {"today": {"$date": "2022-06-24T00:00:00Z"},"tomorrow": {"$date": "2022-06-24T00:00:00Z"}}}
console.log(transformDates(beforeTwo));
Note that Stack Snippets converts Date objects back to string when outputting them. This is not what you would see in a browser's console, where you really get a rendering of Date objects.

Related

Filter an array of objects with latest date if array contains same date with different timestamp in multiple objects

I have an array of objects and each object has the date. I need to filter the array and get the objects that contains latest date.
[
{
"Id": 25,
"MeasureDate": "2022-08-26T00:01:01.001Z"
},
{
"Id": 26,
"MeasureDate": "2022-08-26T11:10:01.001Z"
},
{
"Id": 27,
"MeasureDate": "2022-08-26T16:12:01.001Z"
},
{
"Id": 30,
"MeasureDate": "2022-08-27T00:08:01.001Z"
},
{
"Id": 31,
"MeasureDate": "2022-08-27T10:20:10.001Z"
}
]
After filtering the array I need the array should look like below
[
{
"Id": 27,
"MeasureDate": "2022-08-26T16:12:01.001Z"
},
{
"Id": 31,
"MeasureDate": "2022-08-27T10:20:10.001Z"
}
]
const dateItems = [
{
"Id": 25,
"MeasureDate": "2022-08-26T00:01:01.001Z"
},
{
"Id": 26,
"MeasureDate": "2022-08-26T11:10:01.001Z"
},
{
"Id": 27,
"MeasureDate": "2022-08-26T16:12:01.001Z"
},
{
"Id": 30,
"MeasureDate": "2022-08-27T00:08:01.001Z"
},
{
"Id": 31,
"MeasureDate": "2022-08-27T10:20:10.001Z"
}
];
// As we loop through your dateItems array we need to keep track of the Latest DateTime for each day
// Probably the easiest way is to create a key on a property for each date and then attach the object
// from your array to that key if it is the first for that date or later than an existing one.
const latestDateTimesByDate = {};
dateItems.forEach( di => {
// Use the date part of the date time as a key/ property name on the latestDateTimesByDate object
let dateKey = di.MeasureDate.substring(0, 10);
// If that date key doesnt exist or the current MeasureDate is gretaer than the recorded one
if( !latestDateTimesByDate[dateKey] || di.MeasureDate > latestDateTimesByDate[dateKey].MeasureDate) {
latestDateTimesByDate[dateKey] = di;
}
});
// if you need it as an array then add each of the date properties to an element of an array
const finalArray = [];
Object.keys(latestDateTimesByDate).forEach( key => finalArray.push(latestDateTimesByDate[key]));
Here's a solution for your probleme :
function similarDates(obj){
date_obj = new Date(obj.MeasureDate);
// Getting only the dates with same year, month, day
let sim_dates = popo.filter((objs) => {
date = new Date(objs.MeasureDate)
return date.toDateString() === date_obj.toDateString()
});
// Returning the similare dates
return sim_dates
}
function filterData(array) {
result = []
while(array.length) {
console.log(array)
var sameElement = similarDates(array[0]);
// removing all the treated elements from the array
array = array.filter( ( el ) => !sameElement.includes(el));
result.push(sameElement.sort((a, b) => new Date(b.MeasureDate) - new Date(a.MeasureDate)).shift());
}
return result;
}

How to Store Each Object in Loop?

What I would like to do is to process JSON data and store each object after getting out of the for loop. However, the obj gets updated every iteration, so the objectArray holds only David's information in each element in it. I would like the objArray to hold each of the processed JSON objects (screenshot below). The JSON process is to store search a userId and name and store them in the objectArray. Could someone help me figure out how I could store each object in the objectArray? Thank you in advance.
const obj = {};
var objectArray = [];
var data = [
{
"userId": "123",
"name": "John",
"phoneNumber": "123-456-6789"
},
{
"userId": "345",
"name": "Summer",
"phoneNumber": "535-631-9742"
},
{
"userId" : "789",
"name": "David",
"phoneNumber": "633-753-1352"
}
]
var dataLen = data.length;
var people = data;
createKeyValue = ((key, value) => {
var temp = {};
temp["value"] = value;
obj[key] = temp;
});
while (dataLen > 0) {
for (let [key, value] of Object.entries(data[0])) {
switch(key) {
case 'userId':
createKeyValue(key, value);
break;
case 'name':
createKeyValue(key, value);
break;
default:
}
}
objectArray.push(obj);
data.shift();
dataLen -= 1;
}
You can do this using a simple forEach() loop to create and push new objects to the objArray array.
const data = [
{
"userId": "123",
"name": "John",
"phoneNumber": "123-456-6789"
},
{
"userId": "345",
"name": "Summer",
"phoneNumber": "535-631-9742"
},
{
"userId": "789",
"name": "David",
"phoneNumber": "633-753-1352"
}
];
let objArray = [];
data.forEach(person => {
objArray.push({
userId: { value: person.userId },
name: { value: person.name }
});
});
console.log(objArray);
The error you're seeing is because of a concept in JavaScript (and programming in general) known as "passing by reference."
Objects in JS, instead of being passed as whole groups of data, are passed around as addresses to where that data is stored. This saves a lot of overhead, since objects can become quite large.
In your case however, you're running into one of the ways it can trip you up. Since obj is really getting passed by reference instead of value, you're really .pushing 3 copies of the same address (of obj) onto objectArray rather than 3 distinct sets of data.
A better approach to this problem would be using a JS Array function called map(). This function is probably best explained by MDN:
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
You can use it on your data array like this:
var objectArray = [];
var data = [{
"userId": "123",
"name": "John",
"phoneNumber": "123-456-6789"
},
{
"userId": "345",
"name": "Summer",
"phoneNumber": "535-631-9742"
},
{
"userId": "789",
"name": "David",
"phoneNumber": "633-753-1352"
}
]
objectArray = data.map(dataEl => ({
userId: {
value: dataEl.userId,
},
name: {
value: dataEl.name,
},
}));
console.log(objectArray);
.as-console-wrapper {
max-height: 100% !important;
}
As said by our friends Kevin B and Zcoop98, its more appropriate to use forEach function, not map function:
data.forEach(elem => {
objectArray.push({
userId: { value: elem.userId },
name: { value: elem.name }
});
})

loop through nested object javascript

I am trying to loop through a following nested object and get an output as below:
const preference = {
"ethnicity": {
"value": "Gurung",
"rank": 1
},
"occupation": {
"value": "Banker",
"rank": 2
}
}
I tried following:
let preferenceRank = {};
preference.map(pref => {
preferenceRank[pref.rank] = pref;
});
console.log(preferenceRank);
I get this error:
"TypeError: preference.map is not a function"...
Output required:
{
1: "ethnicity",
2: "occupation",
}
You can use Object.entries to get keys and values at once (as array of arrays [key, value]):
const preference = {
"ethnicity": {
"value": "Gurung",
"rank": 1
},
"occupation": {
"value": "Banker",
"rank": 2
}
}
const preferenceRank = {}
for (const [key, { rank }] of Object.entries(preference)) {
preferenceRank[rank] = key
}
console.log(preferenceRank)
(By the way, in your code it doesn't make any sense to use map there, since you are not mapping the array to anything, and you ignore the return value of map. You probably wanted forEach instead or, as I used now, a for loop.)
2021 Update
There is now an easier way widely available, using Object.fromEntries, which does the opposite of Object.entries, thereby allowing us to express the whole thing as a mapping operation:
const preferenceRank = Object.fromEntries(
Object.entries(preference).map(([key, { rank }]) => [rank, key])
)
You can use the .entries() function to map over the object.
Object.entries(preference).reduce((out, [key, value]) => {
out[value.rank] = key;
return out;
},{});
Use Object.entries() to get an array of the keys and values of the object. You can then loop over that.
Use forEach if the loop is being done for side effect rather than using the values returned by the callback function.
const preference = {
"ethnicity": {
"value": "Gurung",
"rank": 1
},
"occupation": {
"value": "Banker",
"rank": 2
}
}
let preferenceRank = {};
Object.entries(preference).forEach(([pref, {rank}]) => {
preferenceRank[rank] = pref;
});
console.log(preferenceRank);
You could map the entries and build a new object.
const
preference = { ethnicity: { value: "Gurung", rank: 1 }, occupation: { value: "Banker", rank: 2 } },
result = Object.fromEntries(Object
.entries(preference)
.map(([k, { rank }]) => [rank, k])
);
console.log(result);
This will work.
const preferenceRank = {};
Object.keys(preference).forEach((key) => {
preferenceRank[preference[key]['rank']] = preference[key]['value'];
});
console.log(preferenceRank);
You could map over the keys and add to a result-object the rank/key-objects.
const preference = {
"ethnicity": {
"value": "Gurung",
"rank": 1
},
"occupation": {
"value": "Banker",
"rank": 2
}
}
let res= {};
Object.keys(preference).map((el,key) => {
res[preference[el].rank] = el;
});
console.log(res);
map only works for arrays, you are dealing with an object, what you can is go through the keys of the objects by using
Object.keys(preference)
this will return to you the object keys in an array as the following
["ethnicity","occupation"]
then you can map through it if you want and do your code
const preference = {
"ethnicity": {
"value": "Gurung",
"rank": 1
},
"occupation": {
"value": "Banker",
"rank": 2
}
}
console.log({...Object.keys(preference)})

check if key index exists in an associative array Angularjs javascript

From the below json data how can I check if key "type_1" of "no_2" exists, if doesnt exists to push {"p_id": "24","subcat_id": "2","name": "ok"} to the "type_1" of "no_2" array object.
How does key index and array push works here
{
"no_1": {
"orderNumber": "no_1",
"billing_order_id": "1",
"orderArray": {
"type 2": [
{
"p_id": "25",
"subcat_id": "2",
"name": "fine"
},
{
"p_id": "34",
"subcat_id": "2",
"name": "not ok"
}
]
}
},
"no_2": {
"orderNumber": "no_2",
"billing_order_id": "1",
"orderArray": {
"type_1": [
{
"p_id": "6",
"subcat_id": "1",
"name": "hello"
}
]
}
}
}
I think this is what you're trying to do.
(Most JavaScript code is not structured quite this way, but the sample code is verbose for clarity.)
const
myObj = getObj(),
keyToCheck = "no_3",
myArr = [],
myKeys = Object.keys(myObj), // `.keys` is as static method of Object
keyToPush = myKeys[0], // gets first key in list
valueToPush = myObj[keyToPush], // gets value from this key in obj
fullObjToPush = {}; // makes a new empty object
fullObjToPush[keyToPush] = valueToPush; // Makes a new property in obj w/ key and val
// pushes object to array if `keyToCheck` is not found
if(myKeys.includes(keyToCheck)){ /* do nothing */ }
else{ myArr.push(fullObjToPush); }
// prints result
console.log("myArr now contains this object:");
console.log(myArr);
// provides original object
function getObj(){
return {
"no_1": { "orderNumber": "no_1", "billing_order_id": "1" },
"no_2": { "orderNumber": "no_2", "billing_order_id": "1" }
}
}

object index sorting in javascript

I would like to sort the object indexing like array.sort
Input is
"a":{"label":"0",isEnabled":false,"status":1},
"1":{"label":"1",isEnabled":false,"status":1},
"$":{"label":"2",isEnabled":false,"status":1},
"B":{"label":"3",isEnabled":false,"status":1},
"0":{"label":"5",isEnabled":false,"status":1},
"/":{"label":"6",isEnabled":false,"status":1}
expected output
"$":{"label":"2",isEnabled":false,"status":1},
"/":{"label":"6",isEnabled":false,"status":1},
"0":{"label":"5",isEnabled":false,"status":1},
"1":{"label":"1",isEnabled":false,"status":1},
"a":{"label":"0",isEnabled":false,"status":1},
"B":{"label":"3",isEnabled":false,"status":1}
Actual result are, I understand object by default sorting with numbers, but I would like to sort like expected output as above mentioned, Any inputs please?
"0":{"label":"5",isEnabled":false,"status":1},
"1":{"label":"1",isEnabled":false,"status":1},
"$":{"label":"2",isEnabled":false,"status":1},
"/":{"label":"6",isEnabled":false,"status":1},
"a":{"label":"0",isEnabled":false,"status":1},
"B":{"label":"3",isEnabled":false,"status":1}
Ok, object keys sorted and then used for display.
let obj = {
"a": {
"label": "0",
"isEnabled": false,
"status": 1
},
"1": {
"label": "1",
"isEnabled": false,
"status": 1
},
"$": {
"label": "2",
"isEnabled": false,
"status": 1
},
"B": {
"label": "3",
"isEnabled": false,
"status": 1
},
"0": {
"label": "5",
"isEnabled": false,
"status": 1
},
"/": {
"label": "6",
"isEnabled": false,
"status": 1
}
};
// Get keys in sorted order and print.
const arrKeys = Object.getOwnPropertyNames(obj).sort((a, b) => a < b);
arrKeys.forEach(k => console.log(obj[k]));
Since object property order is not guaranteed you next best thing is using Map. With Map the insertion order is honored and you can use it as an index:
The Map object holds key-value pairs and remembers the original
insertion order of the keys.
let obj = { "a":{"label":"0",isEnabled:false,"status":1}, "1":{"label":"1",isEnabled:false,"status":1}, "$":{"label":"2",isEnabled:false,"status":1}, "B":{"label":"3",isEnabled:false,"status":1}, "0":{"label":"5",isEnabled:false,"status":1}, "/":{"label":"6",isEnabled:false,"status":1} }
let regEx = new RegExp(/[^a-zA-Z\d\s:]/)
let sortedKeys = Object.keys(obj).sort((a, b) => {
if (regEx.test(a) && regEx.test(b))
return a.charCodeAt(0) - b.charCodeAt(0)
else
return a.localeCompare(b, 'en', { numeric: true, caseFirst: 'upper'})
})
let mapped = sortedKeys.reduce((r,c) => (r.set(c, obj[c]), r), new Map())
console.log('keys: ', Array.from(mapped.keys()))
console.log('values: ', Array.from(mapped.values()))

Categories