Get array from nested json value objects - javascript

I've been searching an answer for that but didn't found it.
I have an array like:
const data2 = [{
"abc":{
companyCity:"Cupertino",
conpanyName:"Apple"
}
},
{
"def":{
companyCity:"Mountain View",
conpanyName:"Google"
}
}
]
And I'd like to convert to and array like omiting the parent keys:
const data3 = [
{
companyCity:"Cupertino",
companyName:"Apple",
},
{
companyCity:"Mountain View",
companyName:"Google"
}
]
Perhaps, libraries like lodash have a method to achieve that, but didn't find it. Any help would be very appreciated :)

Iterate the array with Array.flatMap() (or lodash's _.flatMap()), and get the an the inner object of each item using Object.values() (or _.values()):
const data = [{"abc":{"companyCity":"Cupertino","conpanyName":"Apple"}},{"def":{"companyCity":"Mountain View","conpanyName":"Google"}}]
const result = data.flatMap(Object.values)
console.log(result)

Related

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);

How to I get a list of objects from a JSON to an array

I have the following JSON-structure:
{
"markets":
{
"Spain":
{
key:value,
key:value,
key:value
},
"France":
{
key:value,
key:value,
key:value
},
}
and I would like to get list/array of the markets like markets=["Spain","France"] from this.
But I am having a tough time iterating over the markets.
Some of my attempts include using data.markets.foreach and data.markets[index]
But it seems impossible to iterate through the objects in a Json if you dont know their names beforehand.
For reference here is the test code I'm trying things out with:
const data = require('../support/steps.json');
var keys = data.markets.foreach(market=>console.log(market));
Sorry if this is a trivial thing but I've been unable to find the answer when searching.
PS. I know I get access each market with data.markets["Spain"] etc but the point is that I don't know which countries are there to begin with.
You can use Object.keys to get all of the market keys as strings in an array.
const data = {
"markets":
{
"Spain":
{
//...
},
"France":
{
//...
},
}
};
console.log(Object.keys(data.markets));
let data = {
"markets":{
Spain: {},
France:{}
}
};
const keys = Object.keys(data.markets)
console.log(keys)

Find the element in json - Using underscore library or other way

I want to find the g:id object in the below given array of objects
If my g:id is like "g:id": "121"
I can find the element like
var item = _.findWhere(obj, {'g:id': '121'});
But what i have is "g:id": ["121"] like an array. How can i find it.
Here's my array of objects.
[
{
"g:id": [
"121"
],
"g:item_group_id": [
"90461"
]
},
{
"g:id": [
"129"
],
"g:item_group_id": [
"90462"
]
}
]
I tried like this var item = _.findWhere(jsonXML, {'g:id'.[0]: '121'}); but it is not valid.
How can i do this by underscore.js or any other way ?
You can use Array.find() with destructuring to get the g:id value from the array:
const arr = [{"g:id":["121"],"g:item_group_id":["90461"]},{"g:id":["129"],"g:item_group_id":["90462"]}]
const result = arr.find(({ 'g:id': [gid] }) => gid === '121')
console.log(result)
Another option is to use Array.includes() to see if the array contains the value (a must if the array may contain more the one value):
const arr = [{"g:id":["121"],"g:item_group_id":["90461"]},{"g:id":["129"],"g:item_group_id":["90462"]}]
const result = arr.find(({ 'g:id': gid }) => gid.includes('121'))
console.log(result)

How to merge array of arrays in one array (in JavaScript)?

I have an array of objects in JavaScript. Each object contains property named "myPropArray", which is actually another array. Here is the structure of this array:
let myBaseArray = [
{
myPropArray: ["s1", "s2"],
someOtherProp: "randomString1"
},
{
myPropArray: ["s2", "s3"],
someOtherProp: "randomString2"
}
]
What I need is to take all arrays under this property and to merge them all in one array, without duplicates (in JavaScript).
Here is my implementation (using lodash):
_.map(myBaseArray , 'myPropArray')
Which is actually returning the following result:
[
["s1", "s2"],
["s2", "s3"]
]
But what I want to accomplish is:
["s1", "s2", "s3"]
Also (if possible) I'm trying to avoid for-each loops, since this needs to me optimized as much as possible and I'm wondering if can be done using lodash mappers or other similar function?
There are already some solutions from this stage where I got (as the solution here) but I would like to find a solution tho this problem which will be specific for my "array or objects which contains properties of type Array"
.
Extract the property's value with Array.map(), flatten by spreading into Array.concat(), and use a Set to get unique values. Spread the Set back to an array:
const myBaseArray = [
{
myPropArray: ["s1", "s2"],
someOtherProp: "randomString1"
},
{
myPropArray: ["s2", "s3"],
someOtherProp: "randomString2"
}
]
const result = [...new Set([].concat(...myBaseArray.map((o) => o.myPropArray)))]
console.log(result)
The lodash way would be to use _.flatMap(), and _.uniq():
const myBaseArray = [
{
myPropArray: ["s1", "s2"],
someOtherProp: "randomString1"
},
{
myPropArray: ["s2", "s3"],
someOtherProp: "randomString2"
}
]
const result = _.uniq(_.flatMap(myBaseArray, 'myPropArray'))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

How to combine values in array by key?

I have data that looks like this:
data = [
[
{"name":"cpumhz","data":[[1433856538,0],[1433856598,0]]},
{"name":"mem","data":[[1433856538,13660],[1433856598,13660]]}
],
[
{"name":"cpumhz","data":[[1433856538,0],[1433856598,0]]},
{"name":"mem","data":[[1433856538,13660],[1433856598,13660]]}
],
[
{"name":"cpumhz","data":[[1433856538,0],[1433856598,0]]},
{"name":"mem","data":[[1433856538,13660],[1433856598,13660]]}
]
];
how would I use map to combine the array items so the data attributes are concatenated?
Like so:
data = [
[
{"name":"cpumhz","data":[[1433856538,0],[1433856598,0],[1433856538,0],[1433856598,0], [1433856538,0],[1433856598,0]]},
{"name":"mem","data":[[1433856538,13660],[1433856598,13660], [1433856538,13660],[1433856598,13660], [1433856538,13660],[1433856598,13660]]}
]
];
I'm getting closer by doing it non-programatically like so:
res = []
cpudata = _.flatten([data[0][0].data, data[1][0].data, data[2][0].data])
res.push({name: 'cpumhz', data: cpudata})
memdata = _.flatten([data[0][1].data, data[1][1].data, data[2][1].data])
res.push({name: 'mem', data: memdata})
http://jsbin.com/bekodirili/7/edit
Look into using the reduce function. Underscore/lodash have equivalent functions.
Essentially you want to take data and reduce it down to 1 array with 2 values. Something like the following should work:
var reducedData = data.reduce(function(prev, cur) {
prev.forEach(function(value, index) {
value.data = value.data.concat(cur[index].data);
});
return prev;
});
You go over each value in data and reduce it. You concat the previous sub-data with the current sub-data and return the new value.
With lodash, you can do something like this:
_(data)
.flatten()
.groupBy('name')
.reduce(function(result, item, key) {
return result.concat([{
name: key,
data: _.flatten(_.pluck(item, 'data'))
}]);
}, []);
You use flatten() to create an array that can then be grouped into an object, based on the name value using groupBy(). At this point, you have an object with two properties - cpuhz and mem.
Now it's easy to reduce() the object into the array you want.

Categories

Resources