Getting rid of a nested for loop to improve performance - javascript

I have a function thats supposed to be merge two objects together based on certain conditions. the vitalsArray is an array of objects that are unsorted that may or may not have corresponding values (i.e systolic to diastolic and vice versa). Basically if certain conditions are met that would mean that the systolic object and the diastolic object are one BP vital and need to be merged.
My question is is there a better way of doing this than a nested forEach loop?
const mergeBloodPressures = (vitalsArray) => {
let ids = []
let finalArray = []
vitalsArray.forEach((tmpBP) => {
vitalsArray.forEach((bp) => {
let matchDate = moment(bp.takenOn).isSame(
moment(tmpBP.takenOn),
"minute"
)
if (
matchDate &&
bp.vitalType.name != tmpBP.vitalType.name &&
!ids.includes(bp.id) &&
!ids.includes(tmpBP.id)
) {
let temp = {}
if (bp.vitalType.name == "diastolic blood pressure") {
temp.diastolic = bp
temp.systolic = tmpBP
} else {
temp.diastolic = tmpBP
temp.systolic = bp
}
ids.push(bp.id)
finalArray.push(temp)
}
})
})
return finalArray
}
Sample Input:
[
{
"patient_id": 716,
"vital_type_id": 2,
"value": "78",
"taken_on": "2022-06-22T14:49:48.948-05:00",
"vitalType": {
"id": 2,
"name": "diastolic_blood_pressure",
"units": "mmHg",
"created_at": "2022-06-22T14:40:43.746-05:00",
"updated_at": "2022-06-22T14:40:43.746-05:00"
},
"id": 9101,
},
{
"patient_id": 716,
"vital_type_id": 1,
"value": "129",
"taken_on": "2022-06-22T14:49:48.948-05:00",
"vital_type": {
"id": 1,
"name": "systolic_blood_pressure",
"units": "mmHg",
"created_at": "2022-06-22T14:40:43.740-05:00",
"updated_at": "2022-06-22T14:40:43.740-05:00"
},
"id": 9102,
}
]
Sample Output:
[
{
"diastolic": {
"patient_id": 716,
"vital_type_id": 2,
"value": "78",
"taken_on": "2022-06-22T14:49:48.948-05:00",
"vitalType": {
"id": 2,
"name": "diastolic_blood_pressure",
"units": "mmHg",
"created_at": "2022-06-22T14:40:43.746-05:00",
"updated_at": "2022-06-22T14:40:43.746-05:00"
},
"id": 9101,
},
"systolic": {
"patient_id": 716,
"vital_type_id": 1,
"value": "129",
"taken_on": "2022-06-22T14:49:48.948-05:00",
"vitalType": {
"id": 1,
"name": "systolic_blood_pressure",
"units": "mmHg",
"created_at": "2022-06-22T14:40:43.740-05:00",
"updated_at": "2022-06-22T14:40:43.740-05:00"
},
"id": 9102
}
}
]

Your input only shows a single patient on a single date but here is an example that extrapolates from that a little to provide a result that is grouped by patient_id and then further grouped by taken_on within that.
The result is of the following shape:
[
{
"patient_id": 1,
"vitals": [
{
"diastolic": {
taken_on: 1,
//...
},
"systolic": {
taken_on: 1,
//...
}
},
{
"diastolic": {
taken_on: 2,
//...
},
"systolic": {
taken_on: 2,
//...
}
}
]
},
{
"patient_id": 2,
"vitals": [
{
"diastolic": {
taken_on: 1,
//...
},
"systolic": {
taken_on: 1,
//...
}
},
//...
]
}
]
To achieve this the example below iterates each element using a for...of loop then retrieves or creates the a patient_id property using logical nullish assignment (??=). It then further retrieves or initializes an object to group into based on taken_on. Finally the result is created by taking the Object.entries() of the grouped object and mapping over it in order to also convert each taken_on object to a an array of values.
const input = [{ "patient_id": 716, "vital_type_id": 2, "value": "78", "taken_on": "2022-06-22T14:49:48.948-05:00", "vitalType": { "id": 2, "name": "diastolic_blood_pressure", "units": "mmHg", "created_at": "2022-06-22T14:40:43.746-05:00", "updated_at": "2022-06-22T14:40:43.746-05:00" }, "id": 9101, }, { "patient_id": 716, "vital_type_id": 1, "value": "129", "taken_on": "2022-06-22T14:49:48.948-05:00", "vital_type": { "id": 1, "name": "systolic_blood_pressure", "units": "mmHg", "created_at": "2022-06-22T14:40:43.740-05:00", "updated_at": "2022-06-22T14:40:43.740-05:00" }, "id": 9102, }];
const vitalTypesById = {
1: 'systolic',
2: 'diastolic'
};
const groupedByPatient = {};
for (const o of input) {
const takenOn = new Date(o.taken_on).setSeconds(0, 0);
const patient = (groupedByPatient[o.patient_id] ??= {});
const patientByDate = (patient[takenOn] ??= {});
patientByDate[vitalTypesById[o.vital_type_id]] = { ...o };
}
const result = Object.entries(groupedByPatient).map(([patient_id, vitals]) => (
{
patient_id,
vitals: Object.values(vitals)
}
));
console.log(JSON.stringify(result, null, 2));

You want to group by patientid and takenon. I would suggest running through the vitals array and stuff it into a dictionary based on vital name.
Conceptually you'd do something like so.
var mydictionary[] = {};
for (val in vitalsarray) {
let key = val.patientId + "." + val.takenOn;
if (mydictionary[key]) {
let list = mydictonary[key];
list.push( val );
} else {
let listo = [];
listo.push( val );
mydictionary[ key ] = listo;
}
}
The above is sort a pseudo code, but that gets you the patient stuff grouped to together. If you get a little slicker, you can actually look at the list and have a further dictionary which contains the vitals by type....

The next provided approach utilizes Array.prototype.reduce where the reducer function aggregates/merges related(same) blood pressure data, based on a unique key which itself is a concatenation of a patient's ID (patient_id) and the date/timestamp of measurement (taken_on).
The result is a key based index/map/object of merged related blood pressure data-items (blood pressure data). Passing such an object to Object.values returns an array of said data items.
function aggregateRelatedBloodPressureData(index, dataItem) {
const { patient_id, taken_on, vital_type } = dataItem;
const relatedDataKey = `${ patient_id }_${ taken_on }`;
const pressureType = vital_type.name.split('_')[0] ?? vital_type.name;
Object
.assign(
index[relatedDataKey] ??= {},
{ [pressureType]: dataItem },
);
return index;
}
const sampleDate = [{
patient_id: 716,
vital_type_id: 2,
value: "78",
taken_on: "2022-06-22T14:49:48.948-05:00",
vital_type: {
id: 2,
name: "diastolic_blood_pressure",
units: "mmHg",
created_at: "2022-06-22T14:40:43.746-05:00",
updated_at: "2022-06-22T14:40:43.746-05:00",
},
id: 9101,
}, {
patient_id: 716,
vital_type_id: 1,
value: "129",
taken_on: "2022-06-22T14:49:48.948-05:00",
vital_type: {
id: 1,
name: "systolic_blood_pressure",
units: "mmHg",
created_at: "2022-06-22T14:40:43.740-05:00",
updated_at: "2022-06-22T14:40:43.740-05:00",
},
id: 9102,
}];
const aggregatedBloodPressureIndex = sampleDate
.reduce(aggregateRelatedBloodPressureData, {});
const aggregatedBloodPressureList = Object
.values(aggregatedBloodPressureIndex);
console.log({
aggregatedBloodPressureIndex,
aggregatedBloodPressureList,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }

Related

How to filtering out the multiple nested object in Javascript object

Javascript
I have a nested array of objects, I'm trying to filter the given array of objects using a property from the third level of its array property value. For example, from the below array I like to filter the entire array using the property ListId: 10
Example
let test = {
"test":true,
"group":[
{
"name":"header",
"value":[
{
"id":"0",
"list":[
{
"ListId":10,
"name":"string1",
"state":"BY",
"techId":0
},
{
"ListId":11,
"name":"string2",
"state":"BY"
},
{
"ListId":12,
"name":"string3",
"state":"BY"
}
]
}
]
},
{
"name":"header2",
"value":[
{
"id":"01",
"list":[
{
"ListId":100,
"name":"string1",
"state":"BY",
"techId":0
},
{
"ListId":111,
"name":"string2",
"state":"BY"
},
{
"ListId":121,
"name":"string3",
"state":"BY"
}
]
}
]
}
]
}
Filtervalue with ListId = 10
Expected output :
{
"test":true,
"group":[
{
"name":"header",
"value":[
{
"id":"0",
"list":[
{
"ListId":10,
"name":"string1",
"state":"BY",
"techId":0
}
]
}
]
}
]
}
How can I use the filter method using javascript to get this expected result?
You can two it in two times :
First, filter the list arrays,
Secondly filter the groups array using the some method
let test= {
"test": true,
"group": [
{
"name": "header",
"value": [
{
"id": "0",
"list": [
{
"ListId": 10,
"name": "string1",
"state": "BY",
"techId": 0
},
{
"ListId": 11,
"name": "string2",
"state": "BY"
},
{
"ListId": 12,
"name": "string3",
"state": "BY"
}
]
}
]
},
{
"name": "header2",
"value": [
{
"id": "01",
"list": [
{
"ListId": 100,
"name": "string1",
"state": "BY",
"techId": 0
},
{
"ListId": 111,
"name": "string2",
"state": "BY"
},
{
"ListId": 121,
"name": "string3",
"state": "BY"
}
]
}
]
}
]
}
test.group.forEach(group => {
group.value.forEach(value => {
value.list = value.list.filter(list => list.ListId === 10)
})
})
test.group = test.group.filter(group => group.value.some(value => value.list.length > 0))
console.log(test)
Note : You should use plural names for you arrays, it helps understanding the data. For example lists not list for the array.
let z ={"group1": [
{
"name": "header",
"value": [
{
"id": 0,
"list": [
{
"ListId": 10,
"Name": "string1"
},
{
"ListId": 11,
"Name": "string2"
}
]
}
]
}
]}
// This function was written from understading that 'group1' is not a fixed property, but part of a dynamic list due to the number '1'
const getItemByListId = (list, listId) => {
const listKeys = Object.keys(list);
const selectedListKey = listKeys.find(key => {
const groupItems = list[key];
const selectedItem = groupItems.find(({ value: nestedItems }) => {
const selectedNestedItem = nestedItems.find(({ list }) => {
const selectedList = list.find(({ ListId }) => ListId === listId)
return selectedList;
});
return selectedNestedItem;
});
return selectedItem;
});
if (!selectedListKey) {
return null;
}
return list[selectedListKey];
};
console.log(getItemByListId(z, 10));

Get object value based on conditions within nested array objects

I have an array of objects called orders:
const orders = [
{
"order_id": 47445,
"order_type": "Wholesale",
"items": [
{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
}
]
}
];
I need to get the quantity when both the order_type (Wholesale) and items.detail.ID (13363) match.
I have so far tried the following:
const result = orders.find(item => item.order_type == "Wholesale").items
.reduce((total, item) => {
if(item.detail.ID == 13363) {
return item.quantity;
}
}, 0);
Where result correctly returns 4
My issue, and I'm sure I am missing something very simple is that when I have multiple items in my orders array, it fails.
const orders = [
{
"order_id": 47445,
"order_type": "Wholesale",
"items": [
{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
},
{
"id": 56,
"department": "Womens",
"type": "Skirt",
"quantity": 12,
"detail": {
"ID": 76884,
"On Sale": 0,
}
},
{
"id": 89,
"department": "Mens",
"type": "Shirts",
"quantity": 20,
"detail": {
"ID": 98223,
"On Sale": 1,
}
}
]
}
];
The same
const result = orders.find(item => item.order_type == "Wholesale").items
.reduce((total, item) => {
if(item.detail.ID == 13363) {
return item.quantity;
}
}, 0);
returns undefined
Thank you
The find helper just returns the first match, so you need to use another helper like filter, like this:
const ID = 13363;
const result = orders
.filter((order) => order.order_type === 'Wholesale')
.reduce((acc, curr) => {
const items = curr.items.filter((item) => item.detail.ID === ID);
console.log(items);
// You can sum the matching items and then push them into the acc array
const quantity = items.reduce((sum, item) => (sum += item.quantity), 0);
acc.push(quantity);
return acc;
}, []);
This will return an array of matching quantities.
Not sure about the use case but here you go
const result = orders.find(item => item.order_type == "Wholesale").items
.reduce((total, item) => {
if (item.detail.ID == 13363) {
total += item.quantity;
}
return total
}, 0);
You can even create a function to make the search dynamic.
const orders = [
{
"order_id": 47445,
"order_type": "Wholesale",
"items": [
{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
},
{
"id": 56,
"department": "Womens",
"type": "Skirt",
"quantity": 12,
"detail": {
"ID": 76884,
"On Sale": 0,
}
},
{
"id": 89,
"department": "Mens",
"type": "Shirts",
"quantity": 20,
"detail": {
"ID": 98223,
"On Sale": 1,
}
}
]
}
];
findMyItem=( ID )=>{
var result = null ;
const result2 = orders.find(item => item.order_type == "Wholesale").items
.map(( item) => {
if(item.detail.ID == ID ) {
result = item.quantity;
}
}, 0);
return result ;
}
console.log( "result" ,findMyItem( 13363 ) )
console.log( "result" ,findMyItem( 98223) )
console.log( "result" ,findMyItem( 76884) )
You could use Array.find() on the orders array to find the correct order, searching for the first order that matches both the order_type and has an item matching the desired itemId (using Array.some()).
If this order exists, we can then find the corresponding item quantity using .find() again,
const orders = [ { "order_id": 47445, "order_type": "Wholesale", "items": [ { "id": 9, "department": "Womens", "type": "Dress", "quantity": 4, "detail": { "ID": 13363, "On Sale": 1, } }, { "id": 56, "department": "Womens", "type": "Skirt", "quantity": 12, "detail": { "ID": 76884, "On Sale": 0, } }, { "id": 89, "department": "Mens", "type": "Shirts", "quantity": 20, "detail": { "ID": 98223, "On Sale": 1, } } ] } ]
function findItemQuantity(orders, orderType, itemId) {
// Find the first order with the right order_type and containing the right item id
const order = orders.find(order => order.order_type = orderType && order.items.some(item => item.detail.ID === itemId));
if (!order) {
return null;
}
const item = order.items.find(item => item.detail.ID === itemId);
if (!item) {
return null;
}
return item.quantity;
}
console.log("Quantity found:", findItemQuantity(orders, 'Wholesale', 13363))
console.log("Quantity found:", findItemQuantity(orders, 'Wholesale', 76884))
const result = orders
.filter(order => order.order_type == "Wholesale")
.map(order => order.items.find(item => item.detail.ID == 13363))
.filter(item => item)
.reduce((total, { quantity }) => quantity + total, 0);
const orders = [{
"order_id": 47445,
"order_type": "Wholesale",
"items": [{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
}]
},
{
"order_id": 47445,
"order_type": "Whole",
"items": [{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
}]
}
]
const result = orders.reduce(v => {
return v.items.map(a => {
if (v.order_type == 'Wholesale' && a.detail.ID == 13363) {
return v
}
})
})
console.log(result)
const orders = [{
"order_id": 47445,
"order_type": "Wholesale",
"items": [{
"id": 9,
"department": "Womens",
"type": "Dress",
"quantity": 4,
"detail": {
"ID": 13363,
"On Sale": 1,
}
}]
}];
var result = null;
const result2 = orders.find(item => item.order_type == "Wholesale").items
.map((item) => {
if (item.detail.ID == 98223) {
result = item.quantity;
}
}, 0);
console.log("result", result)

Group an array of objects based on a specific field

I have an array of objects. I want to group them by a specific field.
[
{
"name": "JOHN",
"type": 1,
"sum": 5
},
{
"name": "SERA",
"type": 1,
"sum": 43
},
{
"name": "SERA",
"type": 2,
"sum": 129
},
{
"name": "JOHN",
"type": 2,
"sum": 200
}
]
The output I expect for grouping by name attribute is as follows.
{
// Group #1
"JOHN": [
{
"type": 2,
"sum": 200
}
{
"type": 1,
"sum": 5
}
],
// Group #2
"SERA":[
{
"type": 1,
"sum": 43
},
{
"type": 2,
"sum": 129
},
]
}
I used nested loops, but unfortunately the execution speed was slow and it did not give the right results.
As if you mentioned, we can use an object instead of an array for the most outer wrapper. And also swap inside one object to an array, then this is a possible solution.
var data = [{"name": "JOHN","type": 1,"sum": 5},{"name": "SERA","type": 1,"sum": 43},{"name": "SERA","type": 2,"sum": 129},{"name": "JOHN","type": 2,"sum": 200}];
var newData = {};
data.forEach( (item) => {
if (!(item['name'] in newData)) {
newData[item['name']] = [];
}
newData[item['name']].push(
{
'type': item['type'],
'sum' : item['sum']
}
);
});
console.log(newData);
Your proposed output structure is not valid, however using Array.reduce you can create an object in which all the properties are arrays of objects:
const data = [
{
"name": "JOHN",
"type": 1,
"sum": 5
},
{
"name": "SERA",
"type": 1,
"sum": 43
},
{
"name": "SERA",
"type": 2,
"sum": 129
},
{
"name": "JOHN",
"type": 2,
"sum": 200
}
];
const result = data.reduce((c, {name, type, sum}) => {
c[name] = c[name] || [];
c[name].push({type, sum});
return c;
}, {});
console.log(result);
One more way with forEach, destructuring and ?? operator
const merge = (arr) => {
const obj = {};
arr.forEach(({ name, ...rest }) => (obj[name] ??= []).push(rest));
return obj;
};
const data = [
{
name: "JOHN",
type: 1,
sum: 5,
},
{
name: "SERA",
type: 1,
sum: 43,
},
{
name: "SERA",
type: 2,
sum: 129,
},
{
name: "JOHN",
type: 2,
sum: 200,
},
];
console.log(merge(data));
You can use this function which take advantage of Array.prototype.reduce to transform the initial data to another structure of array.
let data = [
{
"name": "JOHN",
"type": 1,
"sum": 5
},
{
"name": "SERA",
"type": 1,
"sum": 43
},
{
"name": "SERA",
"type": 2,
"sum": 129
},
{
"name": "JOHN",
"type": 2,
"sum": 200
}
];
function groupedBy(data, field) {
let fieldValues = [...data].reduce((acc, current) => {
return acc.concat(current[field]);
}, []).filter((value, index, self) => {
return self.indexOf(value) === index;
});
let results = fieldValues.reduce((acc, item) => {
let items = [...data].filter(el => {
return el.name === item;
});
items.forEach(i => delete i.name);
return Object.assign(acc, { [item]: items});
}, {});
return results;
}
console.log(groupedBy(data, "name"));

How to find a value in multilevel Array of objects

I'm trying to implement a search box in which if i start searching for a value it will look for the target in an nested array of objects which is like this:--
[
{
"groupId": 1,
"groupName": "Americas",
"groupItems": [
{
"id": 5,
"name": "Brazil",
"parentID": 1,
"parentName": "Americas"
},
{
"id": 6,
"name": "Canada",
"parentID": 1,
"parentName": "Americas"
}
],
"isExpanded": false,
"toggleAllSelection": false
},
{
"groupId": 2,
"groupName": "APAC",
"groupItems": [
{
"id": 7,
"name": "Australia",
"parentID": 2,
"parentName": "APAC"
},
{
"id": 8,
"name": "China",
"parentID": 2,
"parentName": "APAC"
}
],
"isExpanded": false,
"toggleAllSelection": false
},
{
"groupId": 3,
"groupName": "Europe",
"groupItems": [
{
"id": 9,
"name": "Belgium",
"parentID": 3,
"parentName": "Europe"
},
{
"id": 7,
"name": "Austria",
"parentID": 2,
"parentName": "APAC"
},
{
"id": 10,
"name": "Bulgaria",
"parentID": 3,
"parentName": "Europe"
}
],
"isExpanded": false,
"toggleAllSelection": false
}
]
Now i want to search for name property in each groupItems array of objects in group array. and when there is a match my function should return data in same format and as it will be autocomplete so instead of exact match it should be partial match. So if search aus in input box it should return
[{
"groupId": 2,
"groupName": "APAC",
"groupItems": [
{
"id": 7,
"name": "Australia",
"parentID": 2,
"parentName": "APAC"
}],
"isExpanded": false,
"toggleAllSelection": false,
},
{
"groupId": 3,
"groupName": "Europe",
"groupItems": [
{
"id": 7,
"name": "Austria",
"parentID": 2,
"parentName": "APAC"
}
],
"isExpanded": false,
"toggleAllSelection": false
}
]
const findByName = (data, name) => {
const result = data.reduce((m, { groupItems, ...rest }) => {
let mapGrpItems = (groupItems || []).filter((item) =>
item.name.includes(name)
);
if (mapGrpItems.length) {
m.push({ ...rest, groupItems: mapGrpItems });
}
return m;
}, []);
return result;
};
const findByName = (data, name) => {
const result = data.reduce((m, { groupItems, ...rest }) => {
let mapGrpItems = (groupItems || []).filter((item) =>
item.name.includes(name)
);
if (mapGrpItems.length) {
m.push({ ...rest, groupItems: mapGrpItems });
}
return m;
}, []);
return result;
};
const data = [{"groupId":1,"groupName":"Americas","groupItems":[{"id":5,"name":"Brazil","parentID":1,"parentName":"Americas"},{"id":6,"name":"Canada","parentID":1,"parentName":"Americas"}],"isExpanded":false,"toggleAllSelection":false},{"groupId":2,"groupName":"APAC","groupItems":[{"id":7,"name":"Australia","parentID":2,"parentName":"APAC"},{"id":8,"name":"China","parentID":2,"parentName":"APAC"}],"isExpanded":false,"toggleAllSelection":false},{"groupId":3,"groupName":"Europe","groupItems":[{"id":9,"name":"Belgium","parentID":3,"parentName":"Europe"},{"id":7,"name":"Austria","parentID":2,"parentName":"APAC"},{"id":10,"name":"Bulgaria","parentID":3,"parentName":"Europe"}],"isExpanded":false,"toggleAllSelection":false}]
console.log(JSON.stringify(findByName(data, "Aus"), null, 2));
I would definitely attempt to reason through what you're trying to do before just implementing this. Being able to reason through solutions like this is 99% of the job when it comes to programming.
function filterGroups(filter) {
const result = [];
myObj.forEach(group => {
const filteredGroups = group.groupItems.filter(groupItem => {
return groupItem.name.toLowerCase().includes(filter);
});
if (filteredGroups.length > 1) {
result.push({
...group,
groupItems: filteredGroups
});
}
});
return result;
}
You can use Arrays.filter for the group items in each outer object in your JSON array to filter out the items which match your search query. You can write something like this:
let autocomplete = (key) => {
// arr = Your Data
let result = []
arr.forEach(grp=> {
let out = grp
let res = grp.groupItems.filter(item => item.name.toLowerCase().includes(key.toLowerCase()))
if(res.length!=0)
{
out.groupItems = res
result.push(out)}
})
return result

How to set value to json object by condition?

I have a list object returned from server,
example:
{
"items": [
{
"id": 1,
"role": "SYSTEM_ADMIN"
},
{
"id": 2,
"role": "SYSTEM"
},
{
"id": 3,
"role": "USER"
}
]
}
The problem here is that I want to set the rank value of each object in the above json follow the condition:
SYSTEM_ADMIN => rank: 3
SYSTEM => rank: 2
USER => rank 1
example:
{
    "items": [
        {
            "id": 1,
            "role": "SYSTEM_ADMIN",
            "rank": 3
        },
        {
            "id": 2,
            "role": "SYSTEM",
            "rank": 2
        },
        {
            "id": 3,
            "role": "USER",
            "rank": 1
        },
        {
            "id": 4,
            "role": "SYSTEM",
            "rank": 2
        }
    ]
}
How do I use javascript quickly set rank values ​​for the object without if else too much? thanks everyone
As some people suggested, it's best to do it on the server when you create the response.
If you still need to do it on the frontend for some reason, you can create a constant map that stores each role value's rank in an object map:
const rankMap = {
SYSTEM_ADMIN: 3,
SYSTEM: 2,
USER: 1
};
const data = {
"items": [{
"id": 1,
"role": "SYSTEM_ADMIN"
},
{
"id": 2,
"role": "SYSTEM"
},
{
"id": 3,
"role": "USER"
}
]
}
data.items = data.items.map(item => ({
...item,
rank: rankMap[item.role],
}));
console.log(data);
You can create an object which contains rank and then just use map:
let ranks = {SYSTEM_ADMIN: 3, SYSTEM: 2, USER: 1};
let result = items.map(({id, role})=> ({id, role, rank: ranks[role]}));
An example:
let items = [
{
"id": 1,
"role": "SYSTEM_ADMIN"
},
{
"id": 2,
"role": "SYSTEM"
},
{
"id": 3,
"role": "USER"
}
];
let ranks = {SYSTEM_ADMIN: 3, SYSTEM: 2, USER: 1};
let result = items.map(({id, role})=> ({id, role, rank: ranks[role]}));
console.log(result)
I would keep a list of the roles and their respective ranks in a dictionary. The response can then very simply be mapped
let response = {
items: [
{
"id": 1,
"role": "SYSTEM_ADMIN",
},
{
"id": 2,
"role": "SYSTEM",
},
{
"id": 3,
"role": "USER",
},
{
"id": 4,
"role": "SYSTEM",
}
]
}
let rankMap = {
"SYSTEM_ADMIN": 3,
"SYSTEM": 2,
"USER": 1
}
response.items.forEach(i => i['rank'] = rankMap[i.role]);
console.log(response);

Categories