Angular get difference function object key - javascript

I am trying to compare two or multiple objects using difference() function and then use the object(s) key value to push into an array of just url's, but I can't use dot syntax on an object for some reason any hints?
array this.stores
[
{
name: "Google Play"
url: "https://play.google.com"
}
]
array result
[
{
name: "Google Play"
url: "https://play.google.com"
},
{
name: "Steam Store"
url: "https://store.steampowered.com"
}
]
I'm comparing these 2 arrays of objects like this:
const storesDifference = difference(result, this.stores);
// works as it should stores 'Steam Store'
console.log('difference', storesDifference.url);
// I'm trying to return URL key using dot syntax but without any success

managed to solve this problem using filter function. Works as i wanted.
see below:
const array3 = this.stores
.filter((x) => !result.includes(x))
.concat(result.filter((x) => !this.stores.includes(x)));

Related

Comparing integers in different JSON response Arrays with Postman test

I have 2 different JSON responses from 2 different GET methods from postman.
I am trying to write a test to compare them.
the first response is specificYield
[
[
"2020-11-30T00:00:00Z",
50.701604514154944
],
[
"2020-12-31T00:00:00Z",
19.328539610238128
],
[
"2021-01-31T00:00:00Z",
25.183636870929693
]
]
The second response is expectedYield
[
[
"2020-11-30T00:00:00Z",
62.78336503569246
],
[
"2020-12-31T00:00:00Z",
32.97678871921154
],
[
"2021-01-31T00:00:00Z",
40.82916109964013
]
]
I am trying to check that the integer value in the expectedYield array is always greater than the value in the specificYield array
so it will compare the 62.78336503569246 to 50.701604514154944
and then 32.97678871921154 to 19.328539610238128
and so on
The test looks like this so far, but I know im not using objects anymore and am trying to refactor it to just work with arrays.
pm.test("Expected Yield > Specified Yield", function () {
const expectedYield = pm.response.json();
const specificYield = pm.globals.get("specificYield");
Object.values(expectedYield).forEach((record) => {
pm.expect(record[0][1]).to.greaterThan(
Object.values(specificYield).forEach((record) => {
pm.expect(record[0][1]);
})
);
});
});
I don't know PostMan syntax, but the standard JS syntax would be
expectedYield.every((record, i) => record[1] > specificYield[i][1])
The second argument i to the callback function is the index of the element being tested. This is used to compare that record with the corresponding record of the other array.
Then we use every() to check that it's true for the entire array. There's no need to use Object.values() -- that's used to convert the properties of an ordinary object to an array in order to use array methods, but these are already arrays.

Access and extract values from doubly nested array of objects in JavaScript

I have an array of objects and within those objects is another object which contains a particular property which I want to get the value from and store in a separate array.
How do I access and store the value from the name property from the data structure below:
pokemon:Object
abilities:Array[2]
0:Object
ability:Object
name:"blaze"
1:Object
ability:Object
name:"solar-power"
How would I return and display the values in the name property as a nice string like
blaze, solar-power ?
I tried doing something like this but I still get an array and I don't want to do a 3rd loop since that is not performant.
let pokemonAbilities = [];
let test = pokemon.abilities.map((poke) =>
Object.fromEntries(
Object.entries(poke).map(([a, b]) => [a, Object.values(b)[0]])
)
);
test.map((t) => pokemonAbilities.push(t.ability));
Sample Data:
"pokemon": {
"abilities": [
{
"ability": {
"name": "friend-guard",
"url": "https://pokeapi.co/api/v2/ability/132/"
},
"ability": {
"name": "Solar-flare",
"url": "https://pokeapi.co/api/v2/ability/132/"
}
}
]
}
Then I am doing a join on the returned array from above to get a formatted string.
It just seems like the multiple map() loops can be optimized but I am unsure how to make it more efficient.
Thank you.
There is no need for a loop within loop. Try this:
const pokemon = {
abilities: [{
ability: {
name: 'friend-guard',
url: 'https://pokeapi.co/api/v2/ability/132/'
},
}, {
ability: {
name: 'Solar-flare',
url: 'https://pokeapi.co/api/v2/ability/132/'
}
}]
};
const pokemonAbilities = pokemon.abilities.map(item => item.ability.name).join(', ');
console.log(pokemonAbilities);

Filter elements inside an array inside an object inside an array in Javascript returns somes values undefined

I am using a Japanese dictionary API, which allows me to put in a term and return a list of nouns, verbs, adverbs, and others. This is a result of the API. The API returns an array with a list of objects. Each object has its own arrays and in one of these arrays, there is the array with the information I need, like this:
{"data":[
{
"attribution": {"jmdict": true, "jmnedict": false},
"senses": [
{
"english_definitions": [
"sleep"
],
"parts_of_speech": [
"Noun",
"Ichidan verb"
]
},
{
"english_definitions": [
"Sleep"
],
"parts_of_speech": [
"Ichidan verb", "intransitive verb"
]
}
]
}
]
}
I want to filter the result to show only those results that are verbs, excluding the other results.
This is my code to do the filter:
verbArray = jsonData.data
let verbs2 = verbArray.filter(e => e.senses[0].parts_of_speech[0].includes('verb'));
//console.table(verbs2);
This code does the filter and gives me only those results that have the word verb in the string. But only if it is in position one of the array. If the term is in position two or three, will not return it
You can use
let verbs2 = verbArray.filter(e => e.senses[0].parts_of_speech.some(pos=>pos.includes('verb')));
if you only want to iterate all parts of speeches. The Array.prototype.some() will check all parts of speech for the term verb.
If you also want to iterate senses, you can use
let verbs2 = verbArray.filter(e => e.senses.some(sense=> sense.parts_of_speech.some(pos=>pos.includes('verb'))));

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

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.

From single array convert to an array of object with keys coming from a JSON response -JAVASCRIPT-

I am receiving a json response from an API call. I need to store its keys, and create an array of an object. I am intending to this array of an object is created dynamically no matter the keys of the response.
I've already got the keys like this:
const json_getAllKeys = data => {
const keys = data.reduce((keys, obj) => (
keys.concat(Object.keys(obj).filter(key => (
keys.indexOf(key) === -1))
)
), [])
return keys
}
That returned an array (using a sample json):
['name','username', 'email']
But I am trying to use that array to create an array of object that looks like this one
[
{
name: "name",
username: "username",
email: "Email",
}
];
I've been trying mapping the array, but got multiple objects because of the loop, and I need a single one to make it work.
keys.map(i=>({i:i}))
[
{ i: 'id' },
{ i: 'name' },
{ i: 'username' },
{ i: 'email' }
]
Any hint would be useful!
Thanks in advance :D
What you're looking for is Object.fromEntries, which is ECMA2019, I believe, so available in Node >=14 and will be provided as a polyfill if you employ babel.
I can't quite discern what your reduce should produce, but given the sample input, I would write
const input = ['name','username', 'email'];
const result = Object.fromEntries(input.map(name => ([name, name])));
// result == { name: 'name', username: 'username', email: 'email' }
You're definitely on the right track. One thing to remember is the map function will return the SAME number of output as input. So in your example, an array of 3 returns an array of 3 items.
For this reason, map alone is not going to give you what you want. You may be able to map => reduce it. However, here is a way using forEach instead. This isn't a strictly functional programming style solution, but is pretty straight forward and depending on use case, probably good enough.
let keys = ['name','username', 'email'] //you have this array
const obj = {}; // empty object to hold result
keys.forEach(i => {
obj[i] = i; // set the object as you want
})
console.log(obj); // log out the mutated object
// { name: 'name', username: 'username', email: 'email' }

Categories

Resources