how to make nested array objects in javascript in a key value pair format - javascript

array data=[
{
"id":1,
"name":"john",
"income":22000,
"expenses":15000
},
{
"id":2,
"name":"kiran",
"income":27000,
"expenses":13000
},
{
"id":1,
"name":"john",
"income":35000,
"expenses":24000
}
]
i want to make a new array set in following format which is in a key value pair. ie result set.
can you please explain the best method. ? how to achive using foreach.?
tried using foreach method by looping each element. but cant get the desired output format
var result= [ {
"name": "john",
"series": [
{
"name": "income",
"value": 22000
},
{
"name": "expenses",
"value": 15000
},
]
},
{
"name": "kiran",
"series": [
{
"name": "income",
"value": 27000
},
{
"name": "expenses",
"value": 13000
},
]
}]

// Your array
const result = [
{
name: "john",
series: [
{
name: "income",
value: 22000,
},
{
name: "expenses",
value: 15000,
},
],
},
{
name: "kiran",
series: [
{
name: "income",
value: 27000,
},
{
name: "expenses",
value: 13000,
},
],
},
];
// What is .map function?
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
// Output
// map return a new function.
// it's a loop method but more equipped
result.map((item, index) => {
const seriesKeyValues = {};
// forEach is too, it's a loop method.
// but not have a return value,
// just loops and give you item on each loop
item.series.forEach(serie => {
//seriesKeyValues is a object.
// different between seriesKeyValues.serie.name
// it's a bracket notation
// look this documentation
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#computed_property_names
seriesKeyValues[serie.name] = serie.value;
});
// return new Object
// ... is 'spread syntax' basically combine objects
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#spread_properties
// spread syntax is a new way.
// old way is https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
return {
id: index,
name: item.name,
...seriesKeyValues,
};
});
I hope it will help :). if you don't understand any lines of code, i can explain

Related

create an array of objects from another array of objects using typescript with different key value pair

I have JSON format like this I not sure how do I create new array of objects from an different array of object
[
{
"description":"microsoftLocation",
"icon":"Marker",
"data_id":"123",
"reference":"_1_microsoftOffice",
"id":1,
"text":"microsoftOffice"
},
{
"description":"facebookOffice",
"icon":"Marker",
"data_id":"456",
"reference":"_2_facebookOffice",
"id":2,
"text":"_2_microsoftOffice"
},
]
I want the output to look something like this and not sure how to get the dynamic url as well
[
{
"url":"http://localhost:3000/layer?text=microsoftLocation&data_id=123",
"text":"microsoftLocation",
"active":true,
"icon":Marker
},
{
"url":"http://localhost:3000/layer?text=facebookOffice&data_id=123",
"text":"facebookOffice",
"active":true,
"icon":Marker
},
]
You can do it using a map like this:
const data = [{
"description": "microsoftLocation",
"icon": "Marker",
"data_id": "123",
"reference": "_1_microsoftOffice",
"id": 1,
"text": "microsoftOffice"
},
{
"description": "facebookOffice",
"icon": "Marker",
"data_id": "456",
"reference": "_2_facebookOffice",
"id": 2,
"text": "_2_microsoftOffice"
},
];
const newData = data.map(el => ({
url: `http://localhost:3000/layer?text=${el.description}&data_id=${el.data_id}`,
text: el.description,
active: true,
icon: el.icon
}));
console.log(newData);
Just use map method in order to map from the original object properties to the new ones.
const array = [
{
"description":"microsoftLocation",
"icon":"Marker",
"data_id":"123",
"reference":"_1_microsoftOffice",
"id":1,
"text":"microsoftOffice"
},
{
"description":"facebookOffice",
"icon":"Marker",
"data_id":"456",
"reference":"_2_facebookOffice",
"id":2,
"text":"_2_microsoftOffice"
},
];
console.log(array.map(obj => ({ icon: obj.icon, active: true, text: obj.description, url: `http://localhost:3000/layer?text=${obj.description}&data_id=${obj.data_id}`})))

Convert JSON array with nested arrays (tree) to flat JSON array [duplicate]

This question already has answers here:
Find all values by specific key in a deep nested object
(11 answers)
Closed 10 months ago.
I have this JSON array tree that can include any number of nested arrays:
const namesArrayTree = [
{
"name": "Peter"
},
{
"name": "folder1",
"isArray": true,
"namesArray": [
{
"name": "Paul"
},
{
"name": "folder2",
"isArray": true,
"namesArray": [
{
"name": "Mary"
},
{
"name": "John"
}
]
}
]
},
{
"name": "Mark"
}
]
I need to transform it to a flat array including only the names:
const namesArrayFlat = [ "Peter", "Paul", "Mary", "John", "Mark" ]
So I'm using this code to do the transformation:
const namesArrayTree = [
{
"name": "Peter"
},
{
"name": "folder1",
"isArray": true,
"namesArray": [
{
"name": "Paul"
},
{
"name": "folder2",
"isArray": true,
"namesArray": [
{
"name": "Mary"
},
{
"name": "John"
}
]
}
]
},
{
"name": "Mark"
}
] ;
function getNamesList(item) {
let name = item.name;
let isArray = item.isArray;
if (isArray) {
name = item.namesArray.map(getNamesList).join("\r\n");
}
return name;
}
const namesList = namesArrayTree.map(getNamesList).join("\r\n");
const namesArrayFlat = namesList.split("\r\n");
console.log(namesArrayFlat)
The code works well, but I would like to get rid of the extra steps to create a list with the names using join.("\r\n") and then convert to array using split("\r\n").
That is, I would like to reduce the code by removing the following:
function getNamesList(item) {
let name = item.name;
let isArray = item.isArray;
if (isArray) {
/* remove code to join by "\r\n" */
name = item.namesArray.map(getNamesList)
}
return name;
}
/* remove code to create "namesList" constant and remove code to join by "\r\n") */
const namesArrayFlat = namesArrayTree.map(getNamesList)
console.log(namesArrayFlat)
(The above code still returns a tree nested arrays structure)
Any ideas about how to get rid of the extra code? also any suggestions about how to improve the code would be great, thanks!
function getNamesList(item) {
return item.isArray ? item.namesArray.map(getNamesList) : item.name
}
const names = namesArrayTree.map(getNamesList).flat(Infinity)
console.log(names)
You can achieve this with an array reducer as follows:
const namesArray = [
{
"name": "Peter"
},
{
"name": "folder1",
"isArray": true,
"namesArray": [
{
"name": "Paul"
},
{
"name": "folder2",
"isArray": true,
"namesArray": [
{
"name": "Mary"
},
{
"name": "John"
}
]
}
]
},
{
"name": "Mark"
}
] ;
function reduceNamesList(list, item) {
if (item.isArray) {
return item.namesArray.reduce(reduceNamesList, list);
}
list.push(item.name)
return list
}
const namesList = namesArray.reduce(reduceNamesList, [])
console.log(namesList)

how to foreach array to array object in javascript

I'm very confused about doing foreach array to array object in Javascript, I already did a lot of research about foreach object in Javascript and I tried many ways but nothing works. All that I'm trying to achieve is to have data JSON like this :
[
{
"name": "First Data",
"data": [
{
"y": 95,
"total":100,
"md": "1",
"name": "National",
"drillup" : 'level0',
"drilldown" : "3",
"next" : "level2"
}
]
}
,{
"name": "Second Data",
"data": [
{
"y": 95,
"total":100,
"md": "1",
"name": "National",
"drillup" : 'National',
"drilldown" : "3",
"next" : "level2"
}
]
}
]
and I tried to do foreach based on some finding of my research but the result wasn't like what I want or like what I'm try to achieve ..
and here is the script that I tried :
dataFirstSecond = await informationModel.getdata();
Object.entries(dataRegularSecondary).forEach(entry => {
const [key, value] = entry;
returnData[key] = [
{
name: value.name,
data: [{
y: value.y,
total: value.total_ada,
next: 'level_2',
drilldown: true,
}]
}]
});
and here is the result or the output of my script that I try it :
{
"0": [
{
"name": "First Data",
"data": [
{
"y": 22.973,
"total": 17,
"next": "level_2",
"drilldown": true
}
]
}
],
"1": [
{
"name": "Second Data",
"data": [
{
"y": 5.4054,
"total": 4,
"next": "level_2",
"drilldown": true
}
]
}
]
}
can someone help me to achieve the data that I want?
returnData[key] = [{ ... }] should just be returnData.push({ ... }), and make sure returnData is an array (e.g. returnData = [])
If the function informationModel.getdata(); returns an Object you could use the method JSON.stringify(Object) to easily convert and Object to JSON. For example you could try to do to convert this Object to a String then cast the String to JSON.
let JSONString = JSON.stringify(informationModel.getdata());
let JSON_Object = JSON.parse(JSONString);
If dataRegularSecondary is an array and not an object you could use map:
dataRegularSecondary.map(value => {
return {
name: value.name,
data: [{
y: value.y,
total: value.total_ada,
next: 'level_2',
drilldown: true,
}]
}
}
Your question is how to forEach array to array object. Then that means dataRegularSecondary is an array, right? Object.entries returns an array of key value pairs. If you pass an array to that method, it will return the indices as keys and the items as values.
const arr = ['hello', 'world'];
Object.entries(arr); // [['0', 'hello'], ['1', 'world']]
Skip the Object.entries and use dataRegularSecondary directly for forEach.
As for your output, it looks like returnData is an object as well. Make sure it's an array and just push the data into that.
dataRegularSecondary.forEach(value => {
returnData.push({
name: value.name,
data: [{
y: value.y,
total: value.total_ada,
next: 'level_2',
drilldown: true,
}],
});
});
Or you can use map as well.
const returnData = dataRegularSecondary.map(value => ({
name: value.name,
data: [{
y: value.y,
total: value.total_ada,
next: 'level_2',
drilldown: true,
}],
}));

Functional immutable way in javascript to copy an array with additional items in certain positions depending on condition on items

I have an array:
[
{ "name": "batman", "hasSidekick": true },
{ "name": "shazam!", "hasSidekick": false },
{ "name": "capt america", "hasSidekick": true },
{ "name": "spiderman", "hasSidekick": false }
]
From this, I want to create a new array of hero names which will have all of the above names but when hasSidekick is true for a hero, there should be an additional name inserted after it.
Expected output:
[
"batman",
"batman's sidekick",
"shazam!", ,
"capt america",
"capt america's sidekick",
"spiderman"
]
I can do it with forEach and pushing additional items conditionally based on hasSidekick:
const heroes = [
{ name: "batman", hasSidekick: true },
{ name: "shazam!", hasSidekick: false },
{ name: "capt america", hasSidekick: true },
{ name: "spiderman", hasSidekick: false },
];
let heroesAndSidekicks = [];
heroes.forEach(hero => {
heroesAndSidekicks.push(hero.name);
if (hero.hasSidekick) {
heroesAndSidekicks.push(`${hero.name}'s sidekick`);
}
});
console.log(heroesAndSidekicks);
But please suggest how I can do it in functional programming way without mutation.
You could take Array#flatMap.
var data = [{ name: "batman", hasSidekick: true }, { name: "shazam!", hasSidekick: false }, { name: "capt america", hasSidekick: true }, { name: "spiderman", hasSidekick: false }],
result = data.flatMap(({ name, hasSidekick }) => hasSidekick
? [name, name + '\'s sidekick']
: name
);
console.log(result);
I think Array.prototype.reduce() can solve your issue. From the documentation:
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.
Please find a possible solution below:
const data = [
{ "name": "batman", "hasSidekick": true },
{ "name": "shazam!", "hasSidekick": false },
{ "name": "capt america", "hasSidekick": true },
{ "name": "spiderman", "hasSidekick": false }
];
const result = data.reduce((a, e) => {
a.push(e.name);
if (e.hasSidekick) {
a.push(`${e.name}'s sidekick`);
}
return a;
}, []);
console.log(result);
I hope that helps!

How can I flatten nested arrays in JavaScript?

I have complicated array with nested arrays.
For example if I want to get data from last array then I have to write:
partners[0].products[0].campaigns[0].nameCampaign or .type or .price etc.
I'd like to flatten this array. And this is what I expect:
Is it possible at all?
#EDIT
This is part of console.log(JSON.stringify(partners, 0, 4));:
[{
"_id": "57727902d0a069e41a34eece",
"namePartner": "Self",
"products": [{
"_id": "57727910d0a069e41a34eed0",
"nameProduct": "Singl",
"campaigns": [{
"_id": "57727937d0a069e41a34eed1",
"type": "lead",
"nameCampaign": "Camp 0"
}]
}, {
"_id": "5774cb68c594b22815643b37",
"nameProduct": "DrugiPartner"
"campaigns": [{
"_id": "5774cb78c594b22815643b38",
"type": "subscription",
"nameCampaign": "DrugaKampania"
}, {
"_id": "5774cbedc594b22815643b3a",
"type": "subscription",
"nameCampaign": "TrzeciaKampania"
}, {
"_id": "5774cbf9c594b22815643b3b",
"type": "subscription",
"nameCampaign": "CzwartaKampania"
}]
}, {
"_id": "5774cbdbc594b22815643b39",
"nameProduct": "Trzeci"
"campaigns": []
}]
}]
In plain Javascript you could use an array with the references to the wanted items and the arrays and use an iterative recursive approach to get the wanted array.
Edit
For more than one property to add, you could use an array for more than one item.
One property:
{ use: 'namePartner' }
Multiple properties:
{ use: ['nameCampains', 'type'] }
function iter(a, r, l) {
if (Array.isArray(a)) {
a.forEach(function (b) {
var use = level[l].use,
rr = JSON.parse(JSON.stringify(r));
(Array.isArray(use) && use || [use]).forEach(function (c) {
rr[c] = b[c];
});
iter(b[level[l].array], rr, l + 1);
});
return;
}
result.push(r);
}
var partners = [{ namePartner: 'Tesco', products: [{ nameProduct: 'New', campains: [{ nameCampains: 'Apple', type: 'appleType' }, { nameCampains: 'Lenovo', type: 'lenovoType' }] }] }, { namePartner: 'Eko', products: [{ nameProduct: 'Fresh', campains: [{ nameCampains: 'Asus', type: 'asusType' }, { nameCampains: 'Dell', type: 'dellType' }] }, { nameProduct: 'new', campains: [{ nameCampains: 'Samsung', type: 'samsungType' }] }] }],
level = [{ use: 'namePartner', array: 'products' }, { use: 'nameProduct', array: 'campains' }, { use: ['nameCampains', 'type'] }],
result = [];
iter(partners, {}, 0);
console.log(result);
You could use get from lodash:
var CAMPAIGN_NAME_PATH = ['partners', 0, 'products', 0, 'campaigns', 0, 'nameCampaig'];
var campaignName = _.get(JSONObject, CAMPAIGN_NAME_PATH, 'optionalDefaultCampaignName');
Or you could try playing with flatten, flattenDeep and flattenDepth and rearrange the JSON object structure first before accessing it (note that these three methods only work on arrays, not key-value objects).

Categories

Resources