How do I convert nested object to one object [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I would like to convert my below object to a specific format
Product: { "alias":"d8156ad9-06af-45ca-a8eb-17f6148f1bd2",
"manufacturing_company":{
"alias":"1",
"name":"Company",
"status":1
},
"form":{
"alias":"2",
"name":"Suppository",
"status":1
},
"generic":{
"alias":"1",
"name":"Esomeprazole",
"status":1
},
"name":"AA",
"trading_price":15,
"purchase_price":10,
"pack_size":"10",
"is_salesable":true,
"primary_unit":{
"alias":"1",
"name":"Form1",
"status":2
},
"secondary_unit":{
"alias":"1",
"name":"Form1",
"status":2
},
"conversion_factor":25,
"code":"201",
"species":"drfgfgd",
"strength":"96",
"full_name":"AA 96",
"status":1,
"category":{
"alias":"8",
"name":"Test2",
"status":1
},
"subgroup":{
"alias":"4",
"name":"CDCD",
"status":1,
"product_group":{
"id":9,
"alias":"1",
"name":"zsdfasd",
"status":1
}
}
}
to
Product: { "alias":"d8156ad9-06af-45ca-a8eb-17f6148f1bd2",
"manufacturing_company":"1",
"form":"2",
"generic":"1",
"name":"AA",
"trading_price":15,
"purchase_price":10,
"pack_size":"10",
"is_salesable":true,
"primary_unit":"1",
"secondary_unit":"1",
"conversion_factor":25,
"code":"201",
"species":"drfgfgd",
"strength":"96",
"full_name":"AA 96",
"status":1,
"category":"8",
"subgroup":"4"
}

Loop through the object and create a new one based on whether the values are scalar or not:
let obj={Product:{alias:"d8156ad9-06af-45ca-a8eb-17f6148f1bd2",manufacturing_company:{alias:"1",name:"Company",status:1},form:{alias:"2",name:"Suppository",status:1},generic:{alias:"1",name:"Esomeprazole",status:1},name:"AA",trading_price:15,purchase_price:10,pack_size:"10",is_salesable:!0,primary_unit:{alias:"1",name:"Form1",status:2},secondary_unit:{alias:"1",name:"Form1",status:2},conversion_factor:25,code:"201",species:"drfgfgd",strength:"96",full_name:"AA 96",status:1,category:{alias:"8",name:"Test2",status:1},subgroup:{alias:"4",name:"CDCD",status:1,product_group:{id:9,alias:"1",name:"zsdfasd",status:1}}}};
let resObj = {}
Object.entries(obj.Product).map(([key, value]) => {
if(typeof value === "object"){
resObj[key] = value.alias
}else{
resObj[key] = value
}
})
console.log(resObj)

You could take for object alias or the value for creating a new object.
var data = { alias: "d8156ad9-06af-45ca-a8eb-17f6148f1bd2", manufacturing_company: { alias: "1", name: "Company", status: 1 }, form: { alias: "2", name: "Suppository", status: 1 }, generic: { alias: "1", name: "Esomeprazole", status: 1 }, name: "AA", trading_price: 15, purchase_price: 10, pack_size: "10", is_salesable: true, primary_unit: { alias: "1", name: "Form1", status: 2 }, secondary_unit: { alias: "1", name: "Form1", status: 2 }, conversion_factor: 25, code: "201", species: "drfgfgd", strength: "96", full_name: "AA 96", status: 1, category: { alias: "8", name: "Test2", status: 1 }, subgroup: { alias: "4", name: "CDCD", status: 1, product_group: { id: 9, alias: "1", name: "zsdfasd", status: 1 } } },
result = Object.fromEntries(Object
.entries(data)
.map(([k, v]) => [k, v && typeof v === 'object'
? v.alias
: v]
)
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

If data is the json you want to convert , then use the below code to get the desired result.
Object.keys(data).reduce((result , current)=>{
var value = "";
if(typeof(data[current]) == "object")
{
value = data[current]["alias"]
}
else{
value = data[current]
}
var d = {}
d[current] = value;
Object.assign(result,d);
return result;
},{})

Related

How to create another object from an existing object? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I want to create expectedObj from currentObj to be sent as response to the API. How can I do it?
The "value" and "label" will always have same values.
These are fixed set of keys. ignore_whitespace is not needed in expectedObj. No other keys are required to be removed.
let currentObj = {
"partnerId": "1",
"platform": {
"label": "ADP",
"value": "ADP"
},
"subPlatform": {
"value": "Health",
"label": "Health"
},
"activeIndicator": {
"value": "Inactive",
"label": "Inactive"
},
"partnerNotes": "",
"ignore_whitespace": false
}
let expectedObj={
"partnerId": "1",
"platform": "ADP",
"subPlatform": Health,
"activeIndicator": "Inactive",
"partnerNotes": ""
}
What I have tried is this
for let (item in currentObj) {
something
}
This will do the transforms you need (as discussed in the comments, no more keys are expected, values are always the same as labels, etc):
let currentObj = {
"partnerId": "1",
"platform": {
"label": "ADP",
"value": "ADP"
},
"subPlatform": {
"value": "Health",
"label": "Health"
},
"activeIndicator": {
"value": "Inactive",
"label": "Inactive"
},
"partnerNotes": "",
"ignore_whitespace": false
}
let expected = {
...currentObj,
platform: currentObj.platform.value,
subPlatform: currentObj.subPlatform.value,
activeIndicator: currentObj.activeIndicator.value,
}
delete expected.ignore_whitespace;
console.log(expected);
Something like this should do what you're looking for:
const expectedObj = Object.entries(currentObj).reduce((a, [k, v]) => {
if (v?.value !== undefined) a[k] = v.value;
else a[k] = v;
return a;
}, {});
Expand this code snippet for a working example:
const currentObj = {
partnerId: '1',
platform: {
label: 'ADP',
value: 'ADP',
},
subPlatform: {
value: 'Health',
label: 'Health',
},
activeIndicator: {
value: 'Inactive',
label: 'Inactive',
},
partnerNotes: '',
ignore_whitespace: false,
};
const expectedObj = Object.entries(currentObj).reduce((a, [k, v]) => {
if (v?.value !== undefined) a[k] = v.value;
else a[k] = v;
return a;
}, {});
console.log(expectedObj);

Typescript - Extract a unique values from a nested array to a new structurize nested array [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I currently want to extract in this array:
[
{
"date":"2021-04-21",
"time":"05:12",
"status":"Collected",
"caption":"Parcel collected"
},
{
"date":"2019-08-21",
"time":"12:04",
"status":"Awaiting Collection",
"caption":"Parcel is awaiting collection"
},
{
"date":"2019-08-21",
"time":"12:03",
"status":"In-transit",
"caption":"Parcel is in-transit"
}
]
to transform to this array whereas i check on the date and time for the new nested array like this:
[
{
"date":"2021-04-21",
"time":"05:12",
"status":"Collected",
"caption":"Parcel collected"
},
{
"date":"2019-08-21",
[
{
"time":"12:04",
"status":"Awaiting Collection",
"caption":"Parcel is awaiting collection"
},
{
"time":"12:03",
"status":"In-transit",
"caption":"Parcel is in-transit"
}
]
}
]
I have tried filter and reduce but will be much same as initialized array as it takes the whole [i] as unique and not date as unique.
As in your snippet, you need to store nested data in some kind of container. I've named it data.
const array = [
{
date: "2021-04-21",
time: "05:12",
status: "Collected",
caption: "Parcel collected",
},
{
date: "2019-08-21",
time: "12:04",
status: "Awaiting Collection",
caption: "Parcel is awaiting collection",
},
{
date: "2019-08-21",
time: "12:03",
status: "In-transit",
caption: "Parcel is in-transit",
},
];
const result = array.reduce((acc, curr) => {
const index = acc.findIndex((o) => o.date === curr.date);
if (index !== -1) {
const { date, ...rest } = acc[index];
const existTime = curr.time;
const existStatus = curr.status;
const existCaption = curr.caption;
if (!rest.data) {
acc[index] = {
date: date,
data: [
{ ...rest },
{ time: existTime, status: existStatus, caption: existCaption },
],
};
} else {
acc[index].data.push({
time: existTime,
status: existStatus,
caption: existCaption,
});
}
} else {
acc.push({ ...curr });
}
return acc;
}, []);
console.log(result);

Filtering an array under the forEach loop [duplicate]

This question already has answers here:
Filter array of objects with another array of objects
(11 answers)
Closed 1 year ago.
const likedUsers = [{
id: "1"
},
{
id: "2"
}
]
const needToFilter = [{
id: "1",
userInfo: "info"
}, {
id: "2",
userInfo: "info"
},
{
id: "3",
userInfo: "info"
}
]
likedUsers.forEach(item => needToFilter.filter(needToFilter => {
return needToFilter.id !== item.id
}));
console.log(users);
I have two arrays like that and if needToFilter array's user id exist in likedUsers array it need to be gone.
Filtered array be like :
needToFilter => [{id:"3",userInfo:"info"}]
I tried forEach and map but result is the same. I know there is another way but i can't figure out how.
Thank you all guys.
Edit :
All the answers works great in my case but i used Set approach to fix my problem.
Maybe you could create a Set of the likedUsersIds before filtering:
const likedUsers = [
{
id: "1"
},
{
id: "2"
}
];
const needToFilter = [
{
id: "1",
userInfo: "info"
},
{
id: "2",
userInfo: "info"
},
{
id: "3",
userInfo: "info"
}
];
const likedUsersIds = new Set(likedUsers.map(o => o.id));
const filtered = needToFilter.filter(o => !likedUsersIds.has(o.id));
console.log(filtered);
You need to assign the result of needToFilter.filter() to users.
The filtering function can use some() to test whether there's any match in likedUsers.
const likedUsers = [{
id: "1"
},
{
id: "2"
}
]
const needToFilter = [{
id: "1",
userInfo: "info"
}, {
id: "2",
userInfo: "info"
},
{
id: "3",
userInfo: "info"
}
]
const users = needToFilter.filter(n => !likedUsers.some(l => l.id == n.id));
console.log(users);
users = needToFilter.filter(a=> !likedUsers.find(i=> i.id == a.id))
EDIT:
Adding detailed answer so that i can be in same team:
You could use MAP to store liked users then filter if not found in map:
const likedUsers = [
{
"id":"1"
},
{
"id":"2"
}
];
const needToFilter = [
{
"id":"1",
"userInfo":"info"
},
{
"id":"2",
"userInfo":"info"
},
{
"id":"3",
"userInfo":"info"
}
];
const mp = new Map();
likedUsers.forEach(i=>mp.set(i.id,true));
const users = needToFilter.filter(i => !mp.has(i.id));
console.log(users)
Tip: Benefit of Map, complexity will be O(n) instead of O(n^2)

How to find max salary in each department,, [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
How to find max salary in each department?
let emp =[
{
'name':"A",
'sal':86879,
'dept':1
},
{
'name':"B",
'sal':3453674,
'dept':2
},
{
'name':"C",
'sal':568867,
'dept':3
},
{
'name':"D",
'sal':34661,
'dept':1
},
{
'name':"E",
'sal':896556,
'dept':2
},
{
'name':"F",
'sal':67678,
'dept':3
},
{
'name':"G",
'sal':45654,
'dept':4
},{
'name':"H",
'sal':35677,
'dept':4
}
];
You can look through each entry in the array, and check for the highest in each department by storing them in a separate object like this
const maxSal = {};
emp.forEach(e=>{
if (!maxSal[e.dept] || maxSal[e.dept] < e.sal){
maxSal[e.dept] = e.sal;
}
});
maxSal is an object with the keys of the department, the value is the highest salary
You could reduce the array by taking dept and val and collect the max values in an object.
const
data = [{ name: "A", sal: 86879, dept: 1 }, { name: "B", sal: 3453674, dept: 2 }, { name: "C", sal: 568867, dept: 3 }, { name: "D", sal: 34661, dept: 1 }, { name: "E", sal: 896556, dept: 2 }, { name: "F", sal: 67678, dept: 3 }, { name: "G", sal: 45654, dept: 4 }, { name: "H", sal: 35677, dept: 4 }],
result = data.reduce(
(r, { dept, sal }) => (r[dept] = Math.max(r[dept] ?? -Number.MAX_VALUE, sal), r ),
{}
);
console.log(result);
here you go findHighestSallary function will return the highest salary just pass the department no. as an argument.
let emp =[
{
'name':"A",
'sal':86879,
'dept':1
},
{
'name':"B",
'sal':3453674,
'dept':2
},
{
'name':"C",
'sal':568867,
'dept':3
},
{
'name':"D",
'sal':34661,
'dept':1
},
{
'name':"E",
'sal':896556,
'dept':2
},
{
'name':"F",
'sal':67678,
'dept':3
},
{
'name':"G",
'sal':45654,
'dept':4
},{
'name':"H",
'sal':35677,
'dept':4
}
];
function findHighestSallary(dept) {
let myarray = [];
emp.map((x) => {
if(x.dept === dept){
myarray.push(x);
}
})
myarray.sort(function(a, b) {
return b.sal - a.sal;
});
return myarray[0].sal;
}
console.log(findHighestSallary(1));

Push one object to another inside JSON

So for example I have object like this:
{
data: [
{
id: 13,
name: "id13"
},
{
id: 21,
name: "id21"
}
],
included: [
{
id: "13",
badge: true
},
{
id: "21",
badge: false
}
]
}
And now I need to loop over included and push included to data where id is equal.
So after transformation it would have badge in data, for example like this:
{
data: [
{
id: "13",
name: "id13",
included: {
id: "13",
badge: true
},
},
{
id: "21",
name: "id21",
included: {
id: "21",
badge: false
}
}
]
}
of course I tried on my own and I've created this code:
for(let i=0; i<includedLength; i++) {
console.log(a.included[i].id);
for(n=0; n<dataLength; n++) {
console.log(a.data[n]);
if(a.icluded[i].id === a.data[i].id) {
console.log('We have match!!!');
}
}
}
but it doesn't work I have an error in console
Uncaught TypeError: Cannot read property '0' of undefined
This is demo of my code.
All solutions here have gone in the same path as you had, which is not efficient. So I am posting my solution, which is more efficient than the other solutions so far. Read the code comments to understand the optimizations done.
// Convert data array into a map (This is a O(n) operation)
// This will give O(1) performance when adding items.
let dataMap = a.data.reduce((map, item) => {
map[item.id] = item;
return map;
}, {});
// Now we map items from included array into the dataMap object
// This operation is O(n). In other solutions, this step is O(n^2)
a.included.forEach(item => {
dataMap[item.id].included = item;
});
// Now we map through the original data array (to maintain the original order)
// This is also O(n)
let finalResult = {
data: a.data.map(({id}) => {
return dataMap[id];
})
};
console.log(JSON.stringify(finalResult))
Here is my solution, this will provide the required output!
It constains the same standard for loops.
Some points I would like to highlight are,
The id in included property is string, so you can use the + operator to convert it to number.
The Object.assign() method is used so that we create a new copy of the corresponding object. Read more here
var data = {
data: [{
id: 13,
name: "id13"
},
{
id: 21,
name: "id21"
}
],
included: [{
id: "13",
badge: true
},
{
id: "21",
badge: false
}
]
}
var output = {
data: data.data
};
for (var q of data.included) {
for (var j of output.data) {
if (+q.id === j.id) {
j['included'] = Object.assign({}, j);;
}
}
}
console.log(output);
.as-console {
height: 100%;
}
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
It seems like a waste of space to push the whole "included" element into the first array when a match is found (you really need that extra id element in there?) - so this just makes output like
[{id: 1, name: 'name', badge: true},{...}]
If no matching badge element is found, it sets badge to false.
var notJSON = {
data: [
{
id: 13,
name: "id13"
},
{
id: 21,
name: "id21"
}
],
included: [
{
id: "13",
badge: true
},
{
id: "21",
badge: false
}
]
};
var badged = notJSON.data.map(function (el, i) {
el.badge = notJSON.included.find(function (inc) {
return inc.id == el.id;
}).badge || false;
return el;
});
console.log(badged);
Its not a JSON, its an Object. A valid json consists of both its key and value as string. What you are trying to do is manipulate an object. The following code should help in getting the desired output.
const obj ={
data: [
{
id: 13,
name: "id13"
},
{
id: 21,
name: "id21"
}
],
included: [
{
id: "13",
badge: true
},
{
id: "21",
badge: false
}
]
}
for (var i=0; i<obj.data.length;i++){
for(var j=0; j< obj.included.length;j++){
if(obj.data[i].id == obj.included[j].id){
obj.data[i].included={
id: obj.included[j].id,
badge: obj.included[j].badge
}
}
}
}
delete obj.included
console.log(obj)
What I am doing her is:
Checking if id of obj.data is equal to that of obj.included
If they are equal add a new key called "included" in obj[data]
When the loop is over delete the "included" key from obj as its not required anymore.
var obj = {
data: [
{
id: 13,
name: "id13"
},
{
id: 21,
name: "id21"
}
],
included: [
{
id: "13",
badge: true
},
{
id: "21",
badge: false
}
]
};
obj.included.forEach((item) => {
obj.data.forEach(item1 => {
if(item.id == item1.id){
item1.included = item;
}
});
});
delete obj.included;

Categories