Extract property values from nested array of objects and arrays - javascript

I have the following nested array of objects:
[
{
"info": [
{
"period": {
"start": "2020-01-01",
"end": "2020-01-31"
},
"info": [
{
"id": 036,
"name": "john",
},
{
"id": 037,
"name": "inna",
}
]
}
]
},
{
"info": [
{
"period": {
"start": "2020-01-01",
"end": "2020-01-31"
},
"info": [
{
"id": 045,
"name": "carl",
},
{
"id": 056,
"name": "tina",
}
]
}
]
}]
I want to extract all the values of the "name" property and put them in an array.
Output: ["john", "inna", "carl", "tina"].

Try with this code:
const userNames = [];
data.map(item => {
return item.info.map(registry => {
return registry.info.map(user => userNames.push(user.name));
})
})
Output: ["john", "inna", "carl", "tina"]

Related

javascript extract and convert into new array

I have the following array
[ {
"contactId": "a87d096gd5fuop",
"firstName": "John Doe",
"registrationTypes": {
"selectedOptions": [
{
}
],
"subTotal": 1620.003
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"events": {
"selectedOptions": [
{
"id": "1",
"name": "T1",
"value": "4550006:3",
},
{
"id": "2",
"name": "T2",
"value": "4550005:3",
},
{
"id": "3",
"name": "T3",
"value": "4550003:3",
}
],
"subTotal": 135.003
},
"freeNetworkingFunctions": {
},
"total": 1755.0059999999999
},
{
"contactId": "a097f",
"firstName": "David",
"registrationTypes": {
"selectedOptions": [
{}
],
"subTotal": 899.998
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"member": {
"selectedOptions": [
{
}
],
"subTotal": 228.8
},
"events": {
"selectedOptions": [
{
"id": "4",
"name": "T4",
"value": "4550002:2",
},
{
"id": "5",
"name": "T5",
"value": "4550001:2",
},
{
"id": "6",
"name": "T6",
"value": "4550003:2",
}
],
"subTotal": 135.003
},
"total": 1263.801
}
]
From the above array, I want to extract events, loop all the data and get only values. So my new array should be something like this:
[ {
"contactId": "a87d096gd5fuop",
"firstName": "John Doe",
"registrationTypes": {
"selectedOptions": [
{
}
],
"subTotal": 1620.003
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"events": [
"4550006:3"
"4550005:3",
"4550003:3",
],
},
"freeNetworkingFunctions": {
},
"total": 1755.0059999999999
},
{
"contactId": "a097f",
"firstName": "David",
"registrationTypes": {
"selectedOptions": [
{}
],
"subTotal": 899.998
},
"foo1": {
"selectedOptions": [
],
"subTotal": 0
},
"member": {
"selectedOptions": [
{
}
],
"subTotal": 228.8
},
"events": [
"4550004:2"
"4550008:3",
"4550003:3",
],
"subTotal": 135.003
},
"total": 1263.801
}
]
So it should return the original array, however, events value data should be in one array.
var arr = [];
var r(var i=0;i<data.length;i++){
data.push(arr[i].value);
}
var newData = [...data, arr]
However, this doesn't work. Any help would be highly appreciated.
Use map twice - once on the dataset to iterate over the objects, and within that map to get an array of values from the selectedOptions.
const data=[{contactId:"a87d096gd5fuop",firstName:"John Doe",registrationTypes:{selectedOptions:[{}],subTotal:1620.003},foo1:{selectedOptions:[],subTotal:0},events:{selectedOptions:[{id:"1",name:"T1",value:"4550006:3"},{id:"2",name:"T2",value:"4550005:3"},{id:"3",name:"T3",value:"4550003:3"}],subTotal:135.003},freeNetworkingFunctions:{},total:1755.0059999999999},{contactId:"a097f",firstName:"David",registrationTypes:{selectedOptions:[{}],subTotal:899.998},foo1:{selectedOptions:[],subTotal:0},member:{selectedOptions:[{}],subTotal:228.8},events:{selectedOptions:[{id:"4",name:"T4",value:"4550002:2"},{id:"5",name:"T5",value:"4550001:2"},{id:"6",name:"T6",value:"4550003:2"}],subTotal:135.003},total:1263.801}];
const out = data.map(obj => {
// Destructure the selected options from the
// rest of each object
const { events: { selectedOptions }, ...rest } = obj;
// `map` over the options to just get an array of values
const events = selectedOptions.map(option => {
return option.value;
});
// Return a new object with the new events property
// combined with the other properties again
return { ...rest, events };
});
console.log(out);
Additional documentation
Destructuring assignment
Rest parameters
Spread syntax

Get Values Array Inside Array in ES6

How can I get the values of the products array inside of an array. I want to combine the products array?
data = [
{
"id": "ORDER-111",
"products": [
{
"id": "5435",
"productName": "Banana",
}
],
},
{
"id": "ORDER-222",
"products": [
{
"id": "75434",
"productName": "Apple",
},
{
"id": "5345",
"productName": "Mango",
}
],
}
]
EXPECTED OUTPUT
"products": [
{
"id": "5435",
"productName": "Banana",
},
{
"id": "75434",
"productName": "Apple",
},
{
"id": "5345",
"productName": "Mango",
}
],
CODE
console.log(
...data
.reduce((r, { products }) => {
(products || []).forEach((o) => {
r.has(o.id);
});
return r;
}, new Map())
.values()
);
This would be a good place to use .flatMap - in the callback, just navigate to the products subarray of each object:
const data = [
{
"id": "ORDER-111",
"products": [
{
"id": "5435",
"productName": "Banana",
}
],
},
{
"id": "ORDER-222",
"products": [
{
"id": "75434",
"productName": "Apple",
},
{
"id": "5345",
"productName": "Mango",
}
],
}
];
const result = data.flatMap(obj => obj.products);
console.log(result);
In older environments without flatMap, use a polyfill or spread into concat instead:
const data = [
{
"id": "ORDER-111",
"products": [
{
"id": "5435",
"productName": "Banana",
}
],
},
{
"id": "ORDER-222",
"products": [
{
"id": "75434",
"productName": "Apple",
},
{
"id": "5345",
"productName": "Mango",
}
],
}
];
const result = [].concat(...data.map(obj => obj.products));
console.log(result);

Optimizing nested for loop algorithm, Javascript

I am using the pokemon API to build a fun little informational app. I specifically want to have a section detailing the damage relationships of a pokemon. I currently retrieve and format the data as such:
Array [
Object {
"double_damage_from": Array [
Object {
"name": "flying",
"url": "https://pokeapi.co/api/v2/type/3/",
},
Object {
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/",
},
Object {
"name": "bug",
"url": "https://pokeapi.co/api/v2/type/7/",
},
Object {
"name": "fire",
"url": "https://pokeapi.co/api/v2/type/10/",
},
Object {
"name": "ice",
"url": "https://pokeapi.co/api/v2/type/15/",
},
],
"double_damage_to": Array [
Object {
"name": "ground",
"url": "https://pokeapi.co/api/v2/type/5/",
},
Object {
"name": "rock",
"url": "https://pokeapi.co/api/v2/type/6/",
},
Object {
"name": "water",
"url": "https://pokeapi.co/api/v2/type/11/",
},
],
"half_damage_from": Array [
Object {
"name": "ground",
"url": "https://pokeapi.co/api/v2/type/5/",
},
Object {
"name": "water",
"url": "https://pokeapi.co/api/v2/type/11/",
},
Object {
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/",
},
Object {
"name": "electric",
"url": "https://pokeapi.co/api/v2/type/13/",
},
],
"half_damage_to": Array [
Object {
"name": "flying",
"url": "https://pokeapi.co/api/v2/type/3/",
},
Object {
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/",
},
Object {
"name": "bug",
"url": "https://pokeapi.co/api/v2/type/7/",
},
Object {
"name": "steel",
"url": "https://pokeapi.co/api/v2/type/9/",
},
Object {
"name": "fire",
"url": "https://pokeapi.co/api/v2/type/10/",
},
Object {
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/",
},
Object {
"name": "dragon",
"url": "https://pokeapi.co/api/v2/type/16/",
},
],
"name": "grass",
"no_damage_from": Array [],
"no_damage_to": Array [],
},
Object {
"double_damage_from": Array [
Object {
"name": "ground",
"url": "https://pokeapi.co/api/v2/type/5/",
},
Object {
"name": "psychic",
"url": "https://pokeapi.co/api/v2/type/14/",
},
],
"double_damage_to": Array [
Object {
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/",
},
Object {
"name": "fairy",
"url": "https://pokeapi.co/api/v2/type/18/",
},
],
"half_damage_from": Array [
Object {
"name": "fighting",
"url": "https://pokeapi.co/api/v2/type/2/",
},
Object {
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/",
},
Object {
"name": "bug",
"url": "https://pokeapi.co/api/v2/type/7/",
},
Object {
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/",
},
Object {
"name": "fairy",
"url": "https://pokeapi.co/api/v2/type/18/",
},
],
"half_damage_to": Array [
Object {
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/",
},
Object {
"name": "ground",
"url": "https://pokeapi.co/api/v2/type/5/",
},
Object {
"name": "rock",
"url": "https://pokeapi.co/api/v2/type/6/",
},
Object {
"name": "ghost",
"url": "https://pokeapi.co/api/v2/type/8/",
},
],
"name": "poison",
"no_damage_from": Array [],
"no_damage_to": Array [
Object {
"name": "steel",
"url": "https://pokeapi.co/api/v2/type/9/",
},
],
},
]
What I want to do is format it like this.
DamageMap: Map {
"double_damage_from" => Array [
"flying",
"poison",
"bug",
"fire",
"ice",
"ground",
"psychic",
],
"double_damage_to" => Array [
"ground",
"rock",
"water",
"grass",
"fairy",
],
"half_damage_from" => Array [
"ground",
"water",
"grass",
"electric",
"fighting",
"poison",
"bug",
"fairy",
],
"half_damage_to" => Array [
"flying",
"poison",
"bug",
"steel",
"fire",
"grass",
"dragon",
"ground",
"rock",
"ghost",
],
"no_damage_from" => Array [],
"no_damage_to" => Array [
"steel",
],
}
The data is formatted into this map with no duplicate types. This is my current solution.
const keys = [
"double_damage_from",
"double_damage_to",
"half_damage_from",
"half_damage_to",
"no_damage_from",
"no_damage_to",
];
const damageMap = new Map();
for (let i = 0; i < results.length; ++i) {
for (let j = 0; j < keys.length; ++j) {
if (!damageMap.has(keys[j])) {
damageMap.set(keys[j], []);
}
const val = damageMap.get(keys[j]);
const curr = results[i][keys[j]];
for (let k = 0; k < curr.length; ++k) {
if (val.indexOf(curr[k].name) === -1) {
val.push(curr[k].name);
}
}
damageMap.set(keys[j], val);
}
}
return damageMap;
};
It is utterly atrocious... I know this. My problem is that any attempt at optimizing it has so far failed. I have tried using combinations of map and reduce functions to no avail. If anybody can take a look at this and optimize it, it would be greatly appreciated!
You may use Array.prototype.reduce() together with Array.prototype.forEach() instead:
const src = [{"double_damage_from":[{"name":"flying","url":"https://pokeapi.co/api/v2/type/3/",},{"name":"poison","url":"https://pokeapi.co/api/v2/type/4/",},{"name":"bug","url":"https://pokeapi.co/api/v2/type/7/",},{"name":"fire","url":"https://pokeapi.co/api/v2/type/10/",},{"name":"ice","url":"https://pokeapi.co/api/v2/type/15/",},],"double_damage_to":[{"name":"ground","url":"https://pokeapi.co/api/v2/type/5/",},{"name":"rock","url":"https://pokeapi.co/api/v2/type/6/",},{"name":"water","url":"https://pokeapi.co/api/v2/type/11/",},],"half_damage_from":[{"name":"ground","url":"https://pokeapi.co/api/v2/type/5/",},{"name":"water","url":"https://pokeapi.co/api/v2/type/11/",},{"name":"grass","url":"https://pokeapi.co/api/v2/type/12/",},{"name":"electric","url":"https://pokeapi.co/api/v2/type/13/",},],"half_damage_to":[{"name":"flying","url":"https://pokeapi.co/api/v2/type/3/",},{"name":"poison","url":"https://pokeapi.co/api/v2/type/4/",},{"name":"bug","url":"https://pokeapi.co/api/v2/type/7/",},{"name":"steel","url":"https://pokeapi.co/api/v2/type/9/",},{"name":"fire","url":"https://pokeapi.co/api/v2/type/10/",},{"name":"grass","url":"https://pokeapi.co/api/v2/type/12/",},{"name":"dragon","url":"https://pokeapi.co/api/v2/type/16/",},],"name":"grass","no_damage_from":[],"no_damage_to":[],},{"double_damage_from":[{"name":"ground","url":"https://pokeapi.co/api/v2/type/5/",},{"name":"psychic","url":"https://pokeapi.co/api/v2/type/14/",},],"double_damage_to":[{"name":"grass","url":"https://pokeapi.co/api/v2/type/12/",},{"name":"fairy","url":"https://pokeapi.co/api/v2/type/18/",},],"half_damage_from":[{"name":"fighting","url":"https://pokeapi.co/api/v2/type/2/",},{"name":"poison","url":"https://pokeapi.co/api/v2/type/4/",},{"name":"bug","url":"https://pokeapi.co/api/v2/type/7/",},{"name":"grass","url":"https://pokeapi.co/api/v2/type/12/",},{"name":"fairy","url":"https://pokeapi.co/api/v2/type/18/",},],"half_damage_to":[{"name":"poison","url":"https://pokeapi.co/api/v2/type/4/",},{"name":"ground","url":"https://pokeapi.co/api/v2/type/5/",},{"name":"rock","url":"https://pokeapi.co/api/v2/type/6/",},{"name":"ghost","url":"https://pokeapi.co/api/v2/type/8/",},],"name":"poison","no_damage_from":[],"no_damage_to":[{"name":"steel","url":"https://pokeapi.co/api/v2/type/9/",},],},],
result = src.reduce((acc, o) => {
Object.keys(o).forEach(key => {
if(Array.isArray(o[key])){
const match = acc.get(key),
items = o[key].map(({name}) => name)
match ?
match.push(...items) :
acc.set(key, items)
}
})
return acc
}, new Map)
console.log(result)
Does this work out?
I didn't know what to call each subelement from the main values array so thing is what i used. But this just digs into there and pulls out the name from each of the sublevel elements and tallies them up.
I didn't worry about uniqueness but you could (after concat) add a uniq clean up thing.
// where `values` is your initial data structure
const damageMap = values.reduce((memo, thing) => {
Object.keys(thing).forEach(key => {
if (key !== 'name') {
memo[key] = memo[key] || []
memo[key] = memo[key].concat(
thing[key].map(({name}) => name))
}
})
return memo
},{});
Using Array.reduce for collecting the data, Array#forEach to iterate over the elements and Object.entries to get key/values from the object.
let map = arr.reduce((acc, cur) => {
Object.entries(cur).forEach(([key, values]) => {
if (!acc[key] && key !=='name') {
acc[key] = [];
}
if (typeof(values)=== 'object') {
values.forEach(({name}) => {
acc[key].push(name);
});
}
});
return acc;
}, {});
Here for playing arround https://jsfiddle.net/h8kL5gp9/ or try this (with the hole code):
let arr = [
{
"double_damage_from": [
{
"name": "flying",
"url": "https://pokeapi.co/api/v2/type/3/",
},
{
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/",
},
{
"name": "bug",
"url": "https://pokeapi.co/api/v2/type/7/",
},
{
"name": "fire",
"url": "https://pokeapi.co/api/v2/type/10/",
},
{
"name": "ice",
"url": "https://pokeapi.co/api/v2/type/15/",
},
],
"double_damage_to": [
{
"name": "ground",
"url": "https://pokeapi.co/api/v2/type/5/",
},
{
"name": "rock",
"url": "https://pokeapi.co/api/v2/type/6/",
},
{
"name": "water",
"url": "https://pokeapi.co/api/v2/type/11/",
},
],
"half_damage_from": [
{
"name": "ground",
"url": "https://pokeapi.co/api/v2/type/5/",
},
{
"name": "water",
"url": "https://pokeapi.co/api/v2/type/11/",
},
{
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/",
},
{
"name": "electric",
"url": "https://pokeapi.co/api/v2/type/13/",
},
],
"half_damage_to": [
{
"name": "flying",
"url": "https://pokeapi.co/api/v2/type/3/",
},
{
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/",
},
{
"name": "bug",
"url": "https://pokeapi.co/api/v2/type/7/",
},
{
"name": "steel",
"url": "https://pokeapi.co/api/v2/type/9/",
},
{
"name": "fire",
"url": "https://pokeapi.co/api/v2/type/10/",
},
{
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/",
},
{
"name": "dragon",
"url": "https://pokeapi.co/api/v2/type/16/",
},
],
"name": "grass",
"no_damage_from": [],
"no_damage_to": [],
},
{
"double_damage_from": [
{
"name": "ground",
"url": "https://pokeapi.co/api/v2/type/5/",
},
{
"name": "psychic",
"url": "https://pokeapi.co/api/v2/type/14/",
},
],
"double_damage_to": [
{
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/",
},
{
"name": "fairy",
"url": "https://pokeapi.co/api/v2/type/18/",
},
],
"half_damage_from": [
{
"name": "fighting",
"url": "https://pokeapi.co/api/v2/type/2/",
},
{
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/",
},
{
"name": "bug",
"url": "https://pokeapi.co/api/v2/type/7/",
},
{
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/",
},
{
"name": "fairy",
"url": "https://pokeapi.co/api/v2/type/18/",
},
],
"half_damage_to": [
{
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/",
},
{
"name": "ground",
"url": "https://pokeapi.co/api/v2/type/5/",
},
{
"name": "rock",
"url": "https://pokeapi.co/api/v2/type/6/",
},
{
"name": "ghost",
"url": "https://pokeapi.co/api/v2/type/8/",
},
],
"name": "poison",
"no_damage_from": [],
"no_damage_to": [
{
"name": "steel",
"url": "https://pokeapi.co/api/v2/type/9/",
},
],
},
];
let map = arr.reduce((acc, cur) => {
Object.entries(cur).forEach(([key, values]) => {
if (!acc[key] && key !=='name') {
acc[key] = [];
}
if (typeof(values)=== 'object') {
values.forEach(({name}) => {
acc[key].push(name);
});
}
});
return acc;
}, {});
console.log(map);

JSON / JavaScript - find matching values, make them into keys and create new, consolidated object

In vanilla JavaScript, how would I find unique locations from this object and make them keys, and place all items with that location as values. (can install lodash if necessary).
So this:
[
{
"item": {
"id": "cat"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "dog"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "snake"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "bird"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "beer"
},
"location": {
"id": "fridge"
}
}
]
Becomes this:
[
{
"porch": [
{
"id": "cat"
},
{
"id": "dog"
}
]
},
{
"forest": [
{
"id": "snake"
},
{
"id": "bird"
}
]
},
{
"fridge": [
{
"id": "beer"
}
]
}
]
PEN
// modified desired result
[
{
"location": {
"name": "porch",
"items": [
{
"title": "cat"
},
{
"title": "dog"
}
]
}
},
{
"location": {
"name": "forest",
"items": [
{
"title": "snake"
},
{
"title": "bird"
}
]
}
},
{
"location": {
"name": "fridge",
"items": [
{
"title": "beer"
}
]
}
}
]
let obj = [
{
"item": {
"id": "cat"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "dog"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "snake"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "bird"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "beer"
},
"location": {
"id": "fridge"
}
}
]
let result = {};
obj.forEach(({item, location}) => {
if(!result[location.id]) result[location.id] = []
result[location.id].push({title: item.id})
})
result = Object.keys(result).map(key => ({
"location": {
"name": key,
"items": result[key]
}
}))
result contains required output.

linqjs group by multiple levels

I am trying to figure out how to group by at multiple levels:
Given the following input JSON:
[
{
"GroupingMajor": "Fruit",
"Grouping": "Banana",
"Description": "10 Bananas",
"Price": 20609.82,
},
{
"GroupingMajor": "Fruit",
"Grouping": "Apple",
"Description": "13 Apples",
"Price": 4567.98,
},
{
"GroupingMajor": "Dairy",
"Grouping": "Cheese",
"Description": "1 KG",
"Price": 76456.76,
}
]
I would like to create output of type:
{
"name": "root",
"children": [
{
"name": "Fruit",
"children": [
{
{"name": "Apple", "price": 4567.98},
{"name": "Banana", "price": 20609.82}
}]
},
{
"name": "Dairy",
"children": [
{
{"name": "Cheese", "price": 76456.76}
}]
}]
}
That is, data is grouped by "GroupingMajor" and then "Grouping". "Grouping" being a child of the parent "GroupingMajor" category. How can I generate this output using linq.js (JavaScript)?
Here is some JavaScript that I've attempted:
var data = Enumerable.From(dataFood)
.GroupBy(
function (e) {
return {
groupmajor: e.GroupingMajor,
groupminor: e.Grouping
}},
function (e) {
return {
groupmajor: e.GroupingMajor,
groupminor: e.Grouping,
name: e.GroupingMajor,
price: e.Price,
}
},
function (key, g) {
return {
group: key.groupmajor,
groupminor: key.groupminor,
name: g.name,
price: g.price
}
})
.ToArray();
I am not getting a correct grouping and I have no idea how to generate a sub-group.
Any help is appreciated.
Here's how you could construct such a query:
var query = Enumerable.From(data)
.GroupBy(
"$.GroupingMajor", // key
"{ name: $.Grouping, price: $.Price }", // item
"{ name: $, children: $$.ToArray() }" // result
)
.ToArray();
var result = {
name: 'root',
children: query
};
Which would yield the following result:
{
"name": "root",
"children": [
{
"name": "Fruit",
"children": [
{
"name": "Banana",
"price": 20609.82
},
{
"name": "Apple",
"price": 4567.98
}
]
},
{
"name": "Dairy",
"children": [
{
"name": "Cheese",
"price": 76456.76
}
]
}
]
}

Categories