Accessing JSON value with unique named subarrays - javascript

I want to sort a JSON array based on time value in a subarray with the key names of the subarrays being named uniquely.
I'm searching for the method to access key, value update_time of every element in Products so I can use that value in a sorting script.
I have tried sorting the array but can not determine how to access the key, values of the subarrays
Expected behavior should be that every unique_keyname_# element is available for sorting and is sorted for further processing in JavaScript. Ultimately with the newest unique_keyname_# as the first element in a list, based on the update_time key.
var obj = {
"company": {
"department_1": {
"Products": {
"unique_keyname_1": {
"product_owner": "co-worker-1",
"update_time": "unix_timestamp_1"
},
"unique_keyname_5": {
"product_owner": "co-worker-4",
"update_time": "unix_timestamp_45"
},
"unique_keyname_8": {
"product_owner": "co-worker-2",
"update_time": "unix_timestamp_5"
}
}
},
"department_2": {
"Products": {
"unique_keyname_3": {
"product_owner": "co-worker-1",
"update_time": "unix_timestamp_21"
},
"unique_keyname_6": {
"product_owner": "co-worker-2",
"update_time": "unix_timestamp_7"
},
"unique_keyname_4": {
"product_owner": "co-worker-3",
"update_time": "unix_timestamp_75"
}
}
}
}
}

I solved the issue by writing an intermediate script in python which makes the API response a valid array. From there it was fairly easy to sort the data.
Thanks for the replies confirming the data itself was deliverd to me in an inappropriate format!
regards

In your example, there are no arrays.
Anyway, in Javascript you can access a node using . like:
obj.company.department_1.Products.unique_keyname_1
Or using [] which gives you more freedom to use costume fields
obj["company"]["department_1"]["Products"]["unique_keyname_1"]
// can also be more dynamic as:
obj["company"]["department_"+ department_counter]["Products"]["unique_keyname_" + keyname_counter]
Is there a possibility that you will change the structure of your JSON? to make it more manangeable ?
if so, i would recommend the folowing structure:
var products = [
{
department: 'SomeDepartment',
productName: 'Something',
productOwner: 'Someone',
update_time: 'Sometime'
}
]
Then you can sort the array easy using Array.sort()
for the sort topic use this : Sort array of objects by string property value

Related

Add only unique items in a VUE.js v-for loop

I'm pulling a JSON formatted object from a Web API. The items are NIH funding grants and when pulled give a history of each Grant for a particular researcher. I'm only looking to render the max award_notice_date for each separate project_serial_num. I have the elements in descending order so if I do a v-for loop they are all rendered in descending order. So far so good. My question is how I can post only the first one of each of the project_serial_num's so I end up with the information from appl_id 10372234 and 10226173? Trying to filter by using dates does not help because a date may have expired but if it's the first one of that project_serial_num then it needs to be displayed
[{
"appl_id": 10372234,
"subproject_id": null,
"fiscal_year": 2022,
"project_num": "5R01CA261232-02",
"project_serial_num": "CA261232",
"award_notice_date": "2022-03-02T12:03:00Z"
},
{
"appl_id": 10226173,
"subproject_id": null,
"fiscal_year": 2021,
"project_num": "5K07CA214839-05",
"project_serial_num": "CA214839",
"award_notice_date": "2021-08-05T12:08:00Z"
},
{
"appl_id": 10253554,
"subproject_id": null,
"fiscal_year": 2021,
"project_num": "1R01CA261232-01",
"project_serial_num": "CA261232",
"award_notice_date": "2021-03-15T12:03:00Z"
},
{
"appl_id": 9989810,
"subproject_id": null,
"fiscal_year": 2020,
"project_num": "5K07CA214839-04",
"project_serial_num": "CA214839",
"award_notice_date": "2020-07-30T12:07:00Z"
}
]
I used this answer from another question to build this:
YOUR_ARRAY.filter((value, index, self) => self.findIndex(v => v.project_serial_num === value.project_serial_num) === index);
This will return a new array where the objects sharing a project_serial_num are removed, which can be passed directly to v-for, without the need to make a new variable/computed property.
You should create a computed property that will use a Map to store the values - but before adding a value to the Map you will first check whether it is already there and eventually skip the duplicates. Something like this
computed:
{
uniqueProjects()
{
const result = {};
this.apiResult.forEach(project =>
{
if (!result[project.project_serial_num])
{
result[project.project_serial_num] = project;
}
});
return Object.values(result); // we rely on the browser to return values in the order they have been added
}
}

Mongoose: How to extract arrays in subdocuments to a single array in the parent document

An Express server using Mongoose returns the following JSON from the database in one of its routes:
{
"gradeLevel": 12,
"classes": [
{
"className": "A",
"students": [
"student1", "student2","student3"
]
},
{
"className": "B",
"students": [
"student4", "student5","student6"
]
},
{
"className": "C",
"students": [
"student7", "student8","student9"
]
}
]
}
In the client, I'd like to be able to for example efficiently check if a student is in any of the class subdocuments in the parent document. The following are the solutions I've conceived, but am not sure which is best practice:
When a student is pushed to class subdocument, push the student to the parent's students field as well.
Add a new field in the model's toJSON transformation to compile all the students.
Use vanilla Javascript in the client to extract all students
I was at this problem too. But to tackle this you need a separate collection called allStudents for example where the schema of it is as follows
{ nameOfStudent: 'String' className: 'String' }
then aggregate it accordingly with subdoucment. So that wherever you push a new student into allStudents with the className mentioned it will be pushed to the students subdocument of the respective className.
Querying with dot notation, like
.find({"classes.students":"student8"})
will check the students field of each object in the classes array, returning the documents containing the specific student in any class.
Thank you for the answers given. Just sharing another solution using vanilla Javascript that might be of use to those in similar situations:
checkStudent = (batch, student) => {
let result = null
const inClass = (cls) => {
if (cls.students.includes(student)) {
result = cls
return true
}
return false
}
batch.classes.some(inClass)
return result
}

v-show if nested array items match filtered array

I have to write a Vue webapp that will take multiple filters, push them to an array and on a click method, check the filters arrays values and if any of the values match any of the nested values inside the tiles nested array, show the tiles where there is a match. So, my filter array could have:
filters: ['cookies', 'jogging']
And my nested tiles array will have:
tiles: [
{
"name": "Greg",
"food": ["cookies", "chips", "burgers"],
"activities": ["drawing", "watching movies"]
"favourite places": ["the parks", "movie theatre"]
},{
"name": "Robyn",
"food": ["cookies", "hotdogs", "fish"],
"activities": ["reading", "jogging"]
"favourite places": ["beach", "theme parks"]
},{
"name": "John",
"food": ["sushi", "candy", "fruit"],
"activities": ["writing", "planning"]
"favourite places": ["the moon", "venus"]
}
]
In the above example, the tiles that would show would be Robyn, since she likes cookies and jogging.
So far my thinking is writing out a for loop that checks the the values inside the nested array, which I got from this solution:
https://stackoverflow.com/a/25926600/1159683
However i'm failing to make the connection for just showing the item inside a v-for/v-show. I've got the method down for pushing all the filters to the filter array, but when it comes to matching it with the nested array and showing them based on the match, i'm at a loss. Preferably i'd like to write this out in vanilla js (es5).
Any help is appreciated.
Thank you!
computed: {
fullyMatchedTiles () {
// Matches must contain all terms from filter array
return this.tiles.filter(obj=> {
// Filter the filters to get matched count
let matchedFilters = this.filters.filter(filterItem=> {
// Check each property by looping keys
for (key in obj) {
// Only evaluate if property is an array
if (Array.isArray(obj[key])) {
// Return true if filterItem found in obj
if (obj[key].some(r=> filterItem.indexOf(r) >= 0)) {
return true
}
}
}
})
return this.filters.length === matchedFilters.length
})
},
partiallyMatchedTiles () {
// Matches must contain at least one term from filter array
// Check each object in the array
return this.tiles.filter(obj=> {
// Check each property by looping keys
for (key in obj) {
// Only evaluate if property is an array
if (Array.isArray(obj[key])) {
// Return true to the filter function if matched, otherwise keep looping
if (obj[key].some(r=> this.filters.indexOf(r) >= 0)) {
return true
}
}
}
})
},
},
Sorry it's not es5. I love the new features too much to take the time to go back 5 years.
For a full example showing the filtered object returned in vue, check this codepen https://codepen.io/shanemgrey/pen/jOErWbe
I think you were describing doing the filtering in the v-for. It seems like too complex of logic to try to accomplish it with the filtering available in v-for.
I would instead do as shown by breaking down the array in a new computed property and then using the resulting filtered array however you like in the template.

From an array of objects, extract value of properties for each object and put in a different array

I have a group of filters that is an Reactive Forms Object. I’ve taken the property values of the object and pushed it into an array.
// original filters object {claim_number: null, status: "Approved", patient: null, service_date: null}
let filterArr = []
Object.keys(this.filtersForm.value).forEach(filter => {
filterArr.push(this.filtersForm.value[filter])
// filterArr [null, “Approved, null, null]
})
I have a table that is comprised of an array of objects like the following:
"claims":[
{
"billed_amount":141.78,
"claim_number": "6596594-0",
"location":"University Hospital",
"member_id":"A1234567890",
"status":{
"label":"Approved",
"value": "Approved"
}
},
{
"billed_amount":341.70,
"claim_number": "2196524-3",
"location":"Springfield Hospital",
"member_id":"B1234567890",
"status":{
"label":"Pending",
"value":"Pending"
}
},
{
"billed_amount":111.70,
"claim_number": "1233514-5",
"location":"Springfield Hospital",
"member_id":"C1234567890",
"status":{
"label":"Pending",
"value":"Pending"
}
},
{
// ...etc
}
]
I am trying to loop through each row and put the property values in an array, one for each row so I can filter them against filterArr. How can I do that?
My question is similar to this post (From an array of objects, extract value of a property as array
), with the key difference being that I'm trying to create an array per object.
Each object represents a row in a table that I am trying to dynamically filter. So I can't have values from different rows being put into one array.
According to your desired result, I think you can use ES6 functions.
const result = yourTable.map(element => Object.values(element));
Using map() function, you go through all elements, and extract from each object its values.
Unsure what you want to include in your output but the below will loop through an array and return an array to the filter function
const output = claimTable["claims"].map((claim) => {
return claim
}).filter((claim) => {
return claim.billed_amount > 100
})
The above will loop through the claims and 'convert' to an array. The filter will return that claim for all true conditions (in this case, if the billed amount is greater than 100).
This article goes over this and adds a bit more to it.

Getting values of json array in Mocha JS

I have following issue, this json is returned by api:
"products": {
"10432471": {
"id": 10432471
},
"10432481": {
"id": 10432481
}
}
and I need to get names of all variables under products array, how to get them?
That values are constantly changing everyday, so I can not refer to their names
Trying console.log(res.body.menu.categories[i].products.values()); but its not worked.
Any sugesstion how can I get 10432471 and 10432481 from products? Without referring to variable names.
You are able to get that via Object.keys(res.body.menu.categories[i].products)
To get the object properties, the shortest is using Object.keys()
var obj = {"products": {
"10432471": {
"id": 10432471
},
"10432481": {
"id": 10432481
}
}}
var properties = Object.keys(obj.products)
console.log(properties)

Categories

Resources