Javascript - Restructure array of objects - javascript

I currently have an array of objects that looks like this:
[
{
"key":"CES0000000001",
"25568.95655":"29923",
"25568.96078":"31603"
},
{
"key":"CES0000000001",
"25568.96501":"34480",
"25568.96924":"38347"
}
]
I'm trying to figure out the best way to restructure this data to look like this:
[
{
"key":"CES0000000002",
"values": [ [ 25568.95655 , 29923 ] , [ 25568.96078 , 31603 ] ]
},
{
"key":"CES0000000002",
"values": [ [ 25568.96501 , 34480 ] , [ 25568.96924 , 38347 ] ]
}
]
Can anyone provide some advice for this and any good resources for restructuring javascript objects? I'm getting more into visualization using d3.js and data formatting is key.

my solution would be
var arr= [
{
"key":"CES0000000001",
"25568.95655":"29923",
"25568.96078":"31603"
},
{
"25568.96501":"34480",
"25568.96924":"38347"
}
];
var transformed= arr.map(function(obj){
var result= {
key: obj.key,
values: []
}
for (var key in obj) {
if (obj.hasOwnProperty(key) && key !== "key") {
result.values.push([key, obj[key]]);
}
}
return result;
});
console.log(transformed);

This is an old post I see, but I want to share how you could do this with es6 object destructuring and restructuring.
if you have an object...
const obj1 = {
"key":"CES0000000001",
"25568.95655":"29923",
"25568.96078":"31603"
};
you could have:
const restructure = ({key, ...values}) => ({key, Object.entries(values)});
const obj2 = restructure(obj1);
or for the array you could restructure all of them with:
const b = arr.map(({key, ...values}) => ({key, Object.entries(values)}));
or if you are reusing the function...
const b = arr.map(restructure);

Related

Facing issue with Javascript array

I am getting an array of object data from service as below:
outputs
array= [
{id:1,Name:GHI,Gender:Male,DOB:12/1/2020},
{id:1,Name:GHI,Gender:Female,DOB:10/1/2020},
{id:2,Name:ABC,Gender:Male,DOB:02/02/2020},
{id:2,Name:ABC,Gender:Female,DOB:03/04/2019},
{id:3,Name:EFG,Gender:Male,DOB:09/09/2010},
{id:3,Name:EFG,Gender:Female,DOB:08/07/2021}
]
I have applied group by function and mapping by using the key
let key="id";
const groupBy=(array,key)=>{
return Object.entries(array.reduce((result,currentvalue)=>{
(result[currentValues[key]]=result[currentValue[key]]||[]).push(
currentvalue
);
return result;
},{})).map(v=>({[key]:v[0],data:v[1]})));
};
I am able to get data like this
[
{
Id:1,
data:
[
{id:1,Name:GHI,Gender:Male,DOB:12/1/2020},
{id:1,Name:GHI,Gender:Female,DOB:10/1/2020}
]
},
{
Id:2,
data:
[
{id:2,Name:ABC,Gender:Male,DOB:02/02/2020},
{id:2,Name:ABC,Gender:Female,DOB:03/04/3019}
]
}...
]
But I need the out put some thing like this I need to group by Id but need the Name of Id something like this
[
{
Name:GHI,
data:[
{id:1,Name:GHI,Gender:Male,DOB:12/1/2020},
{id:1,Name:GHI,Gender:Female,DOB:10/01/2020}
]
},
{
Name:ABC,
data:[
{id:2,Name:ABC,Gender:Male,DOB:02/02/2020},
{id:2,Name:ABC,Gender:Female,DOB:03/04/2019}
]
},
{
Name:EFG,
data:[
{id:3,Name:EFG,Gender:Male,DOB:09/09/2010},
{id:3,Name:EFG,Gender:Male,DOB:08/07/2021}
]
}
]
Please let me know how to retrieve data in expected format to display on UI.
try with the below code.
var arr = [
{id:1,Name:"GHI",Gender:"Male",DOB:"12/1/2020"},
{id:1,Name:"GHI",Gender:"Female",DOB:"10/1/2020"},
{id:2,Name:"ABC",Gender:"Male",DOB:"02/02/2020"},
{id:2,Name:"ABC",Gender:"Female",DOB:"03/04/2019"},
{id:3,Name:"EFG",Gender:"Male",DOB:"09/09/2010"},
{id:3,Name:"EFG",Gender:"Female",DOB:"08/07/2021"}
]
let temp = {}
arr.forEach((obj) => {
temp[obj.Name] = temp[obj.Name] || [];
temp[obj.Name].push(obj);
});
let output = Object.entries(temp).map(obj => {
return {"Name": obj[0], "data": obj[1]}
});
console.log(JSON.stringify(output, null, 2));
You may go simpler and more readable:
let result = {};
for (const data of array) {
const { Name } = data;
if (!result[Name]) {
result[Name] = { Name, data: [data] };
} else {
result[Name].data.push(data);
}
}

Combine children where parent keys are the same in a array of objects

I have an array of objects with duplicate parent keys:
[
{parent1: {'child_id_1': 'value_child_1'}}
{parent1: {'child_id_1_1': 'value_child_1_1'}}
{parent2: {'child_id_2_1': 'value_child_2_1'}}
{parent2: {'child_id_2_2': 'value_child_2_2'}}
{parent2: {'child_id_2_3': 'value_child_2_3'}}
...
]
And I'm looking for this result:
[
{parent1: {'child_id_1': 'value_child_1'}, {'child_id_1_1': 'value_child_1_1'}}
{parent2: {'child_id_2_1': 'value_child_2_1'}, {'child_id_2_2': 'value_child_2_2'}, {'child_id_2_3': 'value_child_2_3'}}
]
I've tried something similar to this below but it only returns one key pair.
const unique = Array.from(new Set(filteredViews.map(a => a.id)))
.map(id => {
return filteredViews.find(a => a.view_name === id)
})
Any help would be greatly appreciated!
Assuming your data looks like this:
const data = [
{parent1: {'child_id_1': 'value_child_1'}},
{parent1: {'child_id_1_1': 'value_child_1_1'}},
{parent2: {'child_id_2_1': 'value_child_2_1'}},
{parent2: {'child_id_2_2': 'value_child_2_2'}},
{parent2: {'child_id_2_3': 'value_child_2_3'}},
]
Using a vanilla approach you could do:
let unique = {};
data.forEach(d => {
let key = Object.keys(d)[0]; // assuming your object has a single key
if (!unique[key]) { unique[key] = []; }
unique[key].push(d[key]);
});
Resulting in:
{
"parent1": [
{"child_id_1":"value_child_1"},
{"child_id_1_1":"value_child_1_1"}
],
"parent2": [
{"child_id_2_1":"value_child_2_1"},
{"child_id_2_2":"value_child_2_2"},
{"child_id_2_3":"value_child_2_3"}
]
}
Using Array.prototype.reduce:
const srcArr = [
{parent1: {'child_id_1': 'value_child_1'}},
{parent1: {'child_id_1_1': 'value_child_1_1'}},
{parent2: {'child_id_2_1': 'value_child_2_1'}},
{parent2: {'child_id_2_2': 'value_child_2_2'}},
{parent2: {'child_id_2_3': 'value_child_2_3'}},
];
const targetArr = srcArr.reduce((acc, val) => {
let [key] = Object.keys(val);
let obj = acc.find(el => key in el);
if (!obj) acc.push({[key]: [val[key]]});
else obj[key].push(val[key]);
return acc;
}, []);
console.log(targetArr);
/* result:
[
{
"parent1": [
{
"child_id_1": "value_child_1"
},
{
"child_id_1_1": "value_child_1_1"
}
]
},
{
"parent2": [
{
"child_id_2_1": "value_child_2_1"
},
{
"child_id_2_2": "value_child_2_2"
},
{
"child_id_2_3": "value_child_2_3"
}
]
}
]
*/

Ask for help on how to get all the filtered list from specific array

I have an object in an array called "Person".
Within the object "Person", there is an array called "info".
My goal is to get all the values with the prefix "age:" in an array "info" when filtering by "gender:male". So, my desired output will be 1 to 9 because I want also to remove duplicates.
Below is my code but the results are only two values (1 and 4). Maybe the output is one value per person.
I spent a lot of hours playing the code but no luck. That's why I bring my problem here hoping anybody who is an expert on this can help me.
<script>
var array = [
{
"person": {
"info": [
"age:1",
"age:2",
"age:3",
"age:4",
"age:5",
"age:6",
"gender:male"
]
},
"person": {
"info": [
"age:4",
"age:5",
"age:6",
"age:7",
"age:8",
"age:9",
"gender:male"
]
},
"person": {
"info": [
"age:8",
"age:9",
"age:10",
"age:11",
"age:12",
"age:13",
"gender:female"
]
}
}
]
var filteredAges = [];
for (i = 0; i < array.length; i++) {
var infoGroup = array[i].person.info,
ageGroup = [];
for (j = 0; j < infoGroup.length; j++) {
ageGroup.push(infoGroup[j]);
var ageInfo = ageGroup.find(ages => ages.includes('age:'));
};
if (ageInfo) {
if (filteredAges.indexOf(ageInfo) == -1) {
filteredAges.push(ageInfo)
}
}
}
for (i = 0;i < filteredAges.length; i++) {
console.log(filteredAges[i]);
}
</script>
Seems like all your object keys are just person i.e
[
{
person: {...},
person: {...},
person: {...}
}
]
So when the variable array is evaluated it just has one person
You need to restructure your data maybe like below or something similar
Example - 1
[
{ person: {...} },
{ person: {...} },
{ person: {...} },
]
Example - 2
[
[ { person: {...} } ],
[ { person: {...} } ],
[ { person: {...} } ]
]
After fixing this you can try debugging your problem
If you want to get all items in info array that has "age:"
you can use filter like this
const ageInfos = [
"age:8", "age:9",
"age:10", "age:11",
"age:12", "age:13",
"gender:female"
].filter(x => x.startsWith("age:"))
Your output - ageInfos will be
["age:8", "age:9", "age:10", "age:11", "age:12", "age:13"]
You can also use Set to only collect unique strings or just push everything to an array and later use Set to return only unique values like this
const arrayWithDuplicates = ['a', 1, 'a', 2, '1'];
const unique = [...new Set(arrayWithDuplicates)];
console.log(unique); // unique is ['a', 1, 2, '1']
First of all, your JSON is wrong. You just overright person object.
Data structure is really awful, I would recommend you to rethink it.
Assuming person will not be overwritten I came up with this solution.
var array = [
{
"person": {
"info": [
"age:1",
"age:2",
"age:3",
"age:4",
"age:5",
"age:6",
"gender:male"
]
},
"person1": {
"info": [
"age:4",
"age:5",
"age:6",
"age:7",
"age:8",
"age:9",
"gender:male"
]
},
"person2": {
"info": [
"age:8",
"age:9",
"age:10",
"age:11",
"age:12",
"age:13",
"gender:female"
]
}
}
]
let agesArray = []
let ages = []
array.forEach((peopleObj) => {
for (const index in peopleObj) {
ages = peopleObj[index].info.map((age) => {
const ageNumber = age.split(':')[1]
if (parseInt(ageNumber)) {
return ageNumber
}
}).filter(val => !!val)
agesArray = [...agesArray, ...ages]
}
})
Thanks a lot guys. I'll apply all of your ideas and try if it can solve my problem.

Trying to 'map' nested JSON element object (javascript)

I am trying to 'map' nested JSON elements that have objects in order to build HTML. I am not sure what I am doing wrong with the syntax as follows:
array1 = [
{
"name":"test",
"things": [
{ "name":"thing1" },
{ "name": "thing2"}
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`
// pass a function to map
const map1 = array1.things.map(createThingy).join('');
console.log(array1);
// expected output: <p>thing1</p><p>thing2</p>
Thank you in advance for your time and consideration.
Think of the array as an object. It's accessed in a similar way, so if it were an object it would be like this:
let array1 = {
0: {
"name":"test",
"things": [
{ "name": "thing1" },
{ "name": "thing2" }
]
}
};
Therefore, to access its first element directly you need:
array1[0].things
To get your desired outcome you need to the following:
let array1 = [
{
"name": "test",
"things": [
{ "name": "thing1" },
{ "name": "thing2" }
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`;
// pass a function to map
const map1 = array1[0].things.map(createThingy).join('');
console.log(map1);
In case your array can have multiple elements, you can use the following:
let array1 = [
{
"name": "test",
"things": [
{ "name": "thing1" },
{ "name": "thing2" }
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`;
// pass a function to map
const map1 = array1.reduce((acc, elem) => acc + elem.things.map(createThingy).join(''), "");
console.log(map1);
array1 = [
{
"name":"test",
"things": [
{ "name":"thing1" },
{ "name": "thing2"}
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`
// pass a function to map
const map1 = array1[0].things.map(createThingy).join('');
console.log(array1);
console.log(map1);
As Nick Parsons said, you have to loop over the array1 array to get things property.
const array1 = [
{
"name":"test",
"things": [
{ "name":"thing1" },
{ "name": "thing2"}
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`
// pass a function to map
const map1 = array1[0].things.map(createThingy).join('');
console.log(array1);
console.log(map1);
Also, be advised that if your array1 variable is empty or in case there is no things attribute in preferred index, your code code will give error. Be sure to check if they are empty. You can do this by using lodash isEmpty function.
You have to loop over the array1 to get the desired output as Nick Parsons said in the comments.
array1 = [
{
"name":"test",
"things": [
{ "name":"thing1" },
{ "name": "thing2"}
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`
array1.map(item => {
item.map(key => createThingy(key).join(''));
});
// expected output: <p>thing1</p><p>thing2</p>

Destructuring array of objects in es6

In es6, how can i simplify the following lines using destructuring?:
const array0 = someArray[0].data;
const array1 = someArray[1].data;
const array2 = someArray[2].data;
Whether using destructuring would actually be a simplification is debatable but this is how it can be done:
const [
{ data: array0 },
{ data: array1 },
{ data: array2 }
] = someArray
Live Example:
const someArray = [
{ data: 1 },
{ data: 2 },
{ data: 3 }
];
const [
{ data: array0 },
{ data: array1 },
{ data: array2 }
] = someArray
console.log(array0, array1, array2);
What is happening is that you're first extracting each object from someArray then destructuring each object by extracting the data property and renaming it:
// these 2 destructuring steps
const [ obj1, obj2, obj3 ] = someArray // step 1
const { data: array0 } = obj1 // step 2
const { data: array1 } = obj2 // step 2
const { data: array2 } = obj3 // step 2
// written together give
const [
{ data: array0 },
{ data: array1 },
{ data: array2 }
] = someArray
Maybe combine destructuring with mapping for (potentially) more readable code:
const [array0, array1, array2] = someArray.map(item => item.data)
Live Example:
const someArray = [
{ data: 1 },
{ data: 2 },
{ data: 3 }
];
const [array0, array1, array2] = someArray.map(item => item.data)
console.log(array0, array1, array2);
I believe what you actually want is
const array = someArray.map(x => x.data)
If you really want three variables (Hint: you shouldn't), you can combine that mapping with destructuring:
const [array0, array1, array2] = someArray.map(x => x.data)
If you want to do with this pure JS then follow this code snippet. It will help you.
let myArray = [
{
"_id": "1",
"subdata": [
{
"subid": "11",
"name": "A"
},
{
"subid": "12",
"name": "B"
}
]
},
{
"_id": "2",
"subdata": [
{
"subid": "12",
"name": "B"
},
{
"subid": "33",
"name": "E"
}
]
}
]
const array = myArray.map(x => x.subdata).flat(1)
const isExist = (key,value, a) => {
return a.find(item => item[key] == value)
}
let a = array.reduce((acc, curr) => {
if(!isExist('subid', curr.subid, acc)) {
acc.push(curr)
}
return acc
}, [])
console.log(a)
const myInfo = someArray.map((item) => {
const {itemval1, itemval2} = item;
return(
//return data how you want it eg:
<p>{itemval1}</p>
<p>{itemval2}</p>)
})
This is how I did it in react, correct me if m wrong, I'm still new to this world
#Daniel, I presume you were looking to destructure a nested Object in an array of Objects. Following #nem035 was able to extract the nested Object's property using his pattern.
What is happening is that you're first extracting each object from addresses array then destructuring each object by extracting its properties and renaming it including the nested Object:
addresses = [
{
locality:"Sarjapura, Bangalore",
coordinates:{latitude:"12.901160", longitude:"77.711680"}
},
{
locality:"Vadakara, Kozhikode",
coordinates:{latitude:"11.588980", longitude:"75.596450"}
}
]
const [
{locality:loc1, coordinates:{latitude:lat1, longitude:ltd1}},
{locality:loc2, coordinates:{latitude:lat2, longitude:ltd2}}
] = addresses
console.log(`Latitude of Vadakara :: ${lat2}`)

Categories