How to change json structure to look like another json structure - javascript

I want to change my json structure, how can I do it?
im getting a json that looks like this:
body: {
"111111": {
"name": "exp1",
"status": 10000
},
"222222": {
"name": "exp2",
"status": 20000
},
"333333": {
"name": "exp3",
"status": 30000
}
}
but I need it in this structure:
body: {
bulks: [{
"id": "111111",
"name": "exp1",
"status": 100000
}, {
"id": "222222",
"name": "exp2",
"status": 200000
}, {
"id": "333333",
"name": "exp3",
"status": 300000
}]
}
Cause in my html I want to read it like this:
<div *ngIf="showingList">
<div class="list-bg" *ngFor="#bulk of listBulks | async">
ID: {{bulk.id}} name of item: {{bulk.name}}
</div>
</div>

Using Object#entries and Array#map with spread operator.
const data={body:{111111:{name:"exp1",status:1e4},222222:{name:"exp2",status:2e4},333333:{name:"exp3",status:3e4}}};
const res = {body:{bulk:Object
.entries(data.body)
.map(a=>({id: a[0], ...a[1]}))}};
console.log(res);

You can do it using reduce:
var body = {
"111111": {
"name": "exp1",
"status": 10000
},
"222222": {
"name": "exp2",
"status": 20000
},
"333333": {
"name": "exp3",
"status": 30000
}
}
var bodyArray = Object.keys(body).reduce(function(result, key) {
var item = body[key];
item.id = key;
result.push(item)
return result;
}, []);

As a simplest alternative to reduce, you could use the map() function.
const body = {
"111111": {
"name": "exp1",
"status": 10000
},
"222222": {
"name": "exp2",
"status": 20000
},
"333333": {
"name": "exp3",
"status": 30000
}
}
const newArray = Object.keys(body).map(function(key) {
const newObject = {
id: key,
...body[key]
};
return newObject;
});
console.log(newArray);

Related

How to combine multiple JSON object that have same key and value

How to combine JSON objects in the same response that has the same key and value with javascript? This is my data for example:
{
"data": [
{
"name": "A",
"description": {
"location": "location1",
"floor": "floor1",
},
},
{
"name": "A",
"description": {
"location": "location2",
"floor": "floor1",
},
},
{
"name": "B",
"description": {
"location": "location3",
"floor": "floor3",
},
},
]
}
And turn it into this:
{
"data": [
{
"name": "A",
"description": {
"location": ["location1","location2"],
"floor": "floor1",
},
},
{
"name": "B",
"description": {
"location": "location3",
"floor": "floor3",
},
},
]
}
Basically I am someone who is new to learning javascript. Any help would be very helpful, thank you.
You can do:
const data = {data: [{name: 'A',description: {location: 'location1',floor: 'floor1',},},{name: 'A',description: {location: 'location2',floor: 'floor1',},},{name: 'B',description: {location: 'location3',floor: 'floor3',},},],}
const result = {
data: data.data.reduce((a, { name, description }) => {
const index = a.findIndex((d) => d.name === name)
if (index >= 0) {
let location = a[index].description.location
location = Array.isArray(location) ? location : [location]
a[index].description.location = [...location, description.location]
} else {
a.push({ name, description })
}
return a
}, []),
}
console.log(result)
const list = {
"data": [
{
"name": "A",
"description": {
"location": "location1",
"floor": "floor1",
},
},
{
"name": "A",
"description": {
"location": "location2",
"floor": "floor1",
},
},
{
"name": "B",
"description": {
"location": "location3",
"floor": "floor3",
},
},
]
};
const consolidatedData = [];
for (const ele of list.data) {
const isExist = consolidatedData.find(x => x.name === ele.name);
if (!isExist) {
consolidatedData.push({
...ele
})
} else {
const objectKey = consolidatedData.findIndex(x => x.name === ele.name);
if (objectKey > -1) {
const description = consolidatedData[objectKey].description;
const newDes = ele.description;
if (newDes.location !== description.location) {
const data = consolidatedData[objectKey].description;
const added = [data.location, ele.description.location];
delete consolidatedData[objectKey].description.location
consolidatedData[objectKey].description["location"] = added
}
if (newDes.floor !== description.floor){
const data = consolidatedData[objectKey].floor;
const added = [data.floor, ele.description.floor];
delete consolidatedData[objectKey].description.floor
consolidatedData[objectKey].description["floor"] = added
}
}
}
}
console.log(JSON.stringify(consolidatedData, null, 2));
Here is a solution that uses an intermediate bucket object. The desired result object is then constructed from the bucket object:
const input = { "data": [ { "name": "A", "description": { "location": "location1", "floor": "floor1", }, }, { "name": "A", "description": { "location": "location2", "floor": "floor1", }, }, { "name": "B", "description": { "location": "location3", "floor": "floor3", }, }, ] };
let buckets = input.data.reduce((acc, obj) => {
if(!acc[obj.name]) {
acc[obj.name] = {
locations: {},
floors: {}
};
}
acc[obj.name].locations[obj.description.location] = true;
acc[obj.name].floors[obj.description.floor] = true;
return acc;
}, {});
console.log('buckets: ', buckets);
let result = {
data: Object.keys(buckets).map(name => {
let locations = Object.keys(buckets[name].locations);
let floors = Object.keys(buckets[name].floors);
return {
name: name,
description: {
location: locations.length == 1 ? locations[0] : locations,
floor: floors.length == 1 ? floors[0] : floors
}
}
})
};
console.log('result:', result);
Notes:
buckets object:
is created using an array .reduce()
array .reduce() docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
locations and floors are collected using objects instead of arrays, this is to avoid duplicate names
result object:
is using Object.keys(buckets) to get the array of names
.map() transforms each name into the desired object
your unusual array or string value for location and floor is constructed with a conditional

how to get unique values from a list of objects?

Data:
[
{
"name": "Ankh of Anubis",
"rank": {
"_type": "medal",
"current": "ankh-of-anubis"
}
},
{
"name": "Bonus Roulette",
"rank": {
"_type": "medal",
"current": "bonus-roulette"
}
},
{
"name": "jetx",
"rank": {
"_type": "medal",
"current": "jetx"
}
},
{
"name": "Gates of Olympus",
"rank": {
"_type": "trophy",
"current": "gates-of-olympus"
}
},
]
How to filter only unique values,
uniqueValues = ["medal","trophy"]
I tried,
const uniqueTitles = new Set(games.category.title);
const uniqueTitles = [...new Set(games.category.title)] //typescript error.
useEffect(() => {
const uniqueTitles = games.filter((game:any) => {
return new Set(game.category.title);
})
setTitles(uniqueTitles);
},[])
You are using Set as the return value for a filter function. Is it really intended that way?
Given the data:
const data = [
{
"name": "Ankh of Anubis",
"rank": {
"_type": "medal",
"current": "ankh-of-anubis"
}
},
{
"name": "Bonus Roulette",
"rank": {
"_type": "medal",
"current": "bonus-roulette"
}
},
{
"name": "jetx",
"rank": {
"_type": "medal",
"current": "jetx"
}
},
{
"name": "Gates of Olympus",
"rank": {
"_type": "trophy",
"current": "gates-of-olympus"
}
},
]
You can do this:
const uniqueValues = new Set();
data.forEach(record => uniqueValues.add(record.rank._type));
console.log(uniqueValues);
Here's the link.
Assuming your array is called data:
const unique = [...new Set(data.map(item => item.rank._type))];
Credits: https://stackoverflow.com/a/58429784/6320971
Solution similar to your first try :
const data = [{"name":"Ankh of Anubis","rank":{"_type":"medal","current":"ankh-of-anubis"}},{"name":"Bonus Roulette","rank":{"_type":"medal","current":"bonus-roulette"}},{"name":"jetx","rank":{"_type":"medal","current":"jetx"}},{"name":"Gates of Olympus","rank":{"_type":"trophy","current":"gates-of-olympus"}},];
const uniqueValues = new Set(data.map(elem => elem.rank._type));
uniqueValues.forEach(value => console.log(value));
const data = [
{
"name": "Ankh of Anubis",
"rank": {
"_type": "medal",
"current": "ankh-of-anubis"
}
},
{
"name": "Bonus Roulette",
"rank": {
"_type": "medal",
"current": "bonus-roulette"
}
},
{
"name": "jetx",
"rank": {
"_type": "medal",
"current": "jetx"
}
},
{
"name": "Gates of Olympus",
"rank": {
"_type": "trophy",
"current": "gates-of-olympus"
}
},
]
const result = data.filter((item, index) => {
const itemIndex = data.findIndex(i => i.rank._type === item.rank._type)
return itemIndex === index
})
console.log(result)
Simple way:
Array.from(new Set(dataList.map(i => i.name)))

Slicing an Array and producing an object from it

I have an array and it looks as follow:
[
{
"DT_RowId": "row_4758",
"companies": {
"id": 23,
"email": null,
"name": "test"
},
"USERS": {
"UserId": 23
}
},.....
]
How do I slice it and get only "companies": and the result as follows:
[
{
"id": 23,
"email": null,
"name": "test"
},.....
]
to clear some issues I have added the function in which I'm using data.map
fn.loadData = function (data) {
var dataKeys = Object.keys(data);
console.log(data)// 'data' is an object
console.log(data.map(x => x.companies)) ///data.map not a function error
var infiniteList = document.getElementById('infinite-list');
infiniteList.delegate = {
createItemContent: function (i) {
return ons._util.createElement(
'<ons-list-item modifier="chevron" tappable>' + data[dataKeys[i]].name + '</ons-list-item>'
);
},
countItems: function () {
return Object.keys(data).length;
}
};
infiniteList.refresh();
}
as comments told you to do:
const data = [
{
"DT_RowId": "row_4758",
"companies": {
"id": 23,
"email": null,
"name": "test"
},
"USERS": {
"UserId": 23
}
},
{
"DT_RowId": "row_3758",
"companies": {
"id": 24,
"email": null,
"name": "test3"
},
"USERS": {
"UserId": 24
}
},]
console.log(data.map(obj=>obj.companies))
This worked:
const newArray = [];
for (let i = 0; i < companyArray.length; i++) {
newArray.push(companyArray[i].companies);
}
Thanks, everyone

How grab key from api call in this js example

So in the API response example below, focusing on env_variables, I am trying grab the value for secret. I am stuck because as you can see, the name and value are not nested together. I am not familiar with how to grab the value based on the name in this example.
api response:
{
"id": 1146,
"job": {
"name": "jobname1",
},
"env_variables": [
{
"name": {
"name": "test1"
},
"value": {
"value": "10.13.6"
}
},
{
"name": {
"name": "test1"
},
"value": {
"value": "10.13.6"
}
},
],
},
{
"id": 1147,
"job": {
"name": "jobname2",
},
"env_variables": [
{
"name": {
"name": "secret"
},
"value": {
"value": "10.13.7"
}
},
{
"name": {
"name": "test5"
},
"value": {
"value": "10.13.6"
}
},
],
}
js
jobs: []
apiEndpoint = "test.com/api"
fetch(this.apiEndpoint)
.then(response => response.json())
.then(body => {
for(let i=0; i<body.length; i++){
this.jobs.push({
'build_id': JSON.stringify(body[i].id),
'secret': //not sure how to pull the value (10.13.7)
})
}
})
You need nested loops, since there are two nested arrays: the top level of the response is an array of objects, and env_variables contains an array of objects.
fetch(this.apiEndpoint)
.then(response => response.json())
.then(body => {
for (let i = 0; i < body.length; i++) {
let env = body[i].env_variables;
for (let j = 0; j < env.length; j++) {
if (env[j].name.name == "secret") {
this.jobs.push({
'build_id': JSON.stringify(body[i].id),
'secret': env[j].value.value
})
}
}
}
})
You can do something like this inside .then(body=>...
const body = [{ //it looks like brackets [] were lost in OP
"id": 1146,
"job": {
"name": "jobname1",
},
"env_variables": [{
"name": {
"name": "test1"
},
"value": {
"value": "10.13.6"
}
},
{
"name": {
"name": "test1"
},
"value": {
"value": "10.13.6"
}
},
],
},
{
"id": 1147,
"job": {
"name": "jobname2",
},
"env_variables": [{
"name": {
"name": "secret"
},
"value": {
"value": "10.13.7"
}
},
{
"name": {
"name": "test5"
},
"value": {
"value": "10.13.6"
}
},
],
}
];
let secret = null;
body.forEach(b => {
let el = b.env_variables.find(e => e.name.name == 'secret');
if (el) { //found
secret = el.value.value;
return false; //exit forEach
}
});
console.log(secret);
You could also do something like this with Array.forEach and Array.find:
let data = [{ "id": 1146, "job": { "name": "jobname1", }, "env_variables": [{ "name": { "name": "test1" }, "value": { "value": "10.13.6" } }, { "name": { "name": "test1" }, "value": { "value": "10.13.6" } }, ], }, { "id": 1147, "job": { "name": "jobname2", }, "env_variables": [{ "name": { "name": "secret" }, "value": { "value": "10.13.7" } }, { "name": { "name": "test5" }, "value": { "value": "10.13.6" } }, ], } ]
let jobs = []
data.forEach(({id, env_variables}) => jobs.push({
build_id: id,
secret: ((env_variables.find(({name}) =>
name.name === 'secret') || {}).value || {}).value || 'N/A'
// ... other props
}))
console.log(jobs)
Assuming your result is an array, you could do something like this:
let secrets = results.reduce((result, item) => {
let secret = item["env_variables"].find((v) => {return v.name.name === "secret"})
if(secret){
result.push({id:item.id, secret: secret.value.value});
}
return result;
}, []);
This would return an array of objects like {id: 1, secret: ""} for each object in your result set that has a secret.
If you don't care whether the secret is present or not, you could modify the code slightly like this:
let secrets = results.reduce((result, item) => {
let secret = item["env_variables"].find((v) => {return v.name.name === "secret"})
result.push({id:item.id, secret: secret ? secret.value.value : ""});
return result;
}, []);
Which just leaves with you an empty string on the levels where there is no secret.

change value of an array of nested objects to a string

this is the array that i currently have
const myArr = [
{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
I want to map over each nested object inside the array so that the value of each nested object is the value property of that object as a string. so the object would become:
const myArr = [
{
"code": "AC16",
"convictionDate":"2019-03-07"
},
{
"code":"AC20",
"convictionDate": "2019-03-06"
}
]
Ive tried this with no success:
const x = myArr.map((item)=>{
console.log(item)
Object.keys(item).map(function(key,i) {
item[key] = item[key][value];
})
})
You are almost there. Just use array map
const myArr = [{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
let newArray = myArr.map(function(item) {
return {
code: item.code.value,
convictionDate: item.convictionDate.value
}
});
console.log(newArray)
Map the array, and reduce the entries to the required object form:
const myArr = [{"code":{"value":"AC16","description":"text"},"convictionDate":{"value":"2019-03-07"}},{"code":{"value":"AC20","description":"text"},"convictionDate":{"value":"2019-03-06"}}];
const result = myArr.map(o =>
Object.entries(o).reduce((r, [k, { value }]) => ({ ...r, [k]: value }), {})
);
console.log(result);
const myArr = [
{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
let newArray = myArr.map(e => {
return { "code":e.code.value, "convictionDate": e.convictionDate.value}
})
console.log(newArray);
It goes without saying there is some awesome reference material over at W3 Schools, the provide good detail on this in their article here
That said...
Why not simplify the code a little and try this against your array:-
const myArr = [
{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
// PROPOSED SOLUTION CODE
const x = myArr.map((item)=>{
return {code: item.code.value,convictionDate: item.convictionDate.value}
});
// Your Desired Example Provided in Question
const xArr = [
{
"code": "AC16",
"convictionDate":"2019-03-07"
},
{
"code":"AC20",
"convictionDate": "2019-03-06"
}
];
// Output Validation
console.log('Response of Array \'x\'');
console.log(x);
console.log('Your Desired Example');
console.log(xArr);
When using 'map'; we must map the source array ('myArr') to our new target array ('x').
In the context of the example code you have provided, 'data.convictions' is undefined.
The magic is all here:-
const x = myArr.map((item)=>{
return {code: item.code.value,convictionDate: item.convictionDate.value}
});
Happy coding!

Categories