Modify an array of objects inside an array of objects in js - javascript

Hello developers I'm trying to modify an array of objects inside an array of objects before deploying its result to Redux reducer.
The array is obtained through a request to an endpoint, reason why i must to create an instance of writable copy of it , and then proceed on the process
Lest say i have this array:
allProducts= [
{
"product_type": "Bikes",
"product_imgs": [
{
"id": 5,
"url": "Mountain Bike/Screenshot (200)"
},
{
"id": 6,
"url": "Mountain Bike/Screenshot (200)"
}
],
"product_name": "product test 1"
},
{
"product_type": "Bikes",
"product_imgs": [
{
"id": 7,
"url": "City Bike/banderaa"
},
{
"id": 8,
"url": "City Bike/banderaa"
}
],
"product_name": "product test 2"
}
]
I would like to modify the items inside the array product_imgs of each object , but for that , having in mind this array comes from a request , i do create a readable copy an over that i set the logic.
let instance=[...allProducts];
then using a double for each (though i also tried using a doule for loop) i reach till every image inside the array of objects product_imgs of each object :
instance.forEach(array=>array.product_imgs.map(element => {
this.imgDownLoaderFirebase
.ref(element.url)
.getDownloadURL()
.toPromise()
.then((url) => {
console.log(url);
//then in this space once the url of some firebase endpoint is reached and else
//i would like to modify that object inside the array product_imgs which is at the same time
//part of the instance array.
//For that i expose that this new url gotten would be asigned as the new
//value thus
element = { ...element };
element.url=url
console.log(element);
console.log(instance);//Printing the general array in order to check if changes committed
})
})
I want to specify that i use first a foreach and then a map in order to modify the inner array of objects result , but using a double for each doesn't precisely inmprove this situation:
instance.forEach(array=>array.product_imgs.forEach(element => {........
Then checking the logs , the element (item url) inside the array of objects product_imgs of the array of obejcts instance , is modified , but the external array containing the inner modified not
How could i improve this?
Thanks

If your goal is to extract all product_img values from your array, you could try something like the following :
// This line will convert your array of object into an array of array of urls, using a destructuring process
const urls = allProducts.map(({ product_img }) => product_img);
// This line will merge the previous result into a single-level array of urls that you can iterate onto.
const result = [].concat([], ...res);
Edit : I forgot to mention that this process will in fact return an array of objects including your id and url.

Related

Dexie: How to get only one column in the result by column key? (simple array of values insted of objects)

I have this fetch query
await useDatabase.data.where("ts").between(ms - 1000, ms).toArray();
I get the result properly but as an object of data.
[
{
"ts": 60.1875,
"sample": 0,
"id": 1
},
{
...
},
{
...
},
]
is it possible to minimise the size of the result by choosing a single column instead of getting a whole object result of a row?
(for sample)
[0,...]
didn't find anything in docs. maybe i'm missing it or using the wrong search keywords.
Not unless you have a compound index of the queried column along with the other column you'd like to return.
const useDatabase = new Dexie('myDatabase');
useDatabase.version(2).stores({
data: 'id, [ts+sample]'
]);
await useDatabase.data.where("[ts+sample]").between(
[ms - 1000, Dexie.minKey],
[ms, Dexie.maxKey]
).keys();
This will give an array of [ms, sample] tuples only.
[
[60.1875, 0],
...
]
You could map it to only get the 'sample' prop:
result.map(([ts, sample]) => sample)
But if performance is of no concert, you could always do this from the original request (without adding the index):
result.map(({sample}) => sample)

Compare array in javascript and create a new array of elements which is being removed

I've got two color arrays and I want to return those objects which are in local array and are not available in API response.
API resposne array
[
{
"id": 25,
"color": "#00ad02"
},
{
"id": 28,
"color": "#e1b12c"
}
]
Local array
[
{
"id": 26,
"color": "#00ad02",
},
{
"color": "#e1b12c",
"id": 28,
}
]
Loop over both arrays and return the one which are not contained by the API response array. Here I am seeking output of id 25.
The array's filter and some method can be used to find the elements which does not exist in another array.
The filter method creates a new array with all elements that pass the test implemented by the provided function. Read here
The some method tests whether at least one element in the array passes the test implemented by the provided function. It returns true if, in the array, it finds an element for which the provided function returns true; otherwise it returns false. It doesn't modify the array. Read here
const notFoundElements = aprResponse.filter(
(r) => !localResponse.some((l) => l.id === r.id)
);
apiResponsesArr.filter(resValue => !localArr.some(localValue => localValue.id===resValue.id))

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.

Accessing JSON value with unique named subarrays

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

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.

Categories

Resources