Reputation: 51
I want to take a list of users and categorize them in a new array to be rendered by my app.
What I am given:
OnlineList = [
{
"Role": "Adjuster",
"AccountId": "4",
"UserId": "1e72d58e",
"DisplayName": "Big Bob",
},
{
"Role": "Adviser",
"AccountId": "5",
"UserId": "a0daba73",
"DisplayName": "Sassy Sally",
}
];
What result I want:
OnlineUsers = {
"Dealership": [
{
"Role": "Adviser",
"AccountId": "Dealership",
"UserId": "a0daba73",
"DisplayName": "Sassy Sally",
}
],
"ClaimsCo": [
{
"Role": "Adjuster",
"AccountId": "ClaimsCo",
"UserId": "1e72d58e",
"DisplayName": "Big Bob",
}
]
}
Result I get:
OnlineUsers = {
"5": [ <----------- Problem
{
"Role": "Adviser",
"AccountId": "5", <----------- Problem
"UserId": "a0daba73",
"DisplayName": "Sassy Sally",
}
],
"ClaimsCo": [
{
"Role": "Adjuster",
"AccountId": "Dealership",
"UserId": "1e72d58e",
"DisplayName": "Big Bob",
}
]
}
Here is a JFiddle I set up replicating the problem: http://jsfiddle.net/vc4mjwx3/20/
My code:
// loaded from API Request into array
var OnlineList = [];
// Sorted and ordered for display
var OnlineUsers = [];
OnlineList = [
{
"Role": "Adjuster",
"AccountId": "4",
"UserId": "1e72d58e",
"DisplayName": "Big Bob",
},
{
"Role": "Adviser",
"AccountId": "5",
"UserId": "a0daba73",
"DisplayName": "Sassy Sally",
}
];
// GroupBy function: https://stackoverflow.com/questions/14446511/most-efficient-method-to-groupby-on-an-array-of-objects/43215522
let groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
// Simulates a get by Id API service
let accountService = (id) => {
if (id == 4) {
return "ClaimsCo."
}
else {
return "Dealership"
}
}
// pass in AccountId
let getAccountName = function(int) {
var accountName = "";
//get AccountName from Id
accountName = accountService(int);
for(var x=0; x < OnlineList.length; x++){
// check for AccountId
if(OnlineList[x].hasOwnProperty('AccountId')){
// Set AccountId value to AccountName
OnlineList[x].AccountId = accountName;
// Group results and set to OnlineUsers array
OnlineUsers = groupBy(OnlineList, 'AccountId');
break;
}
}
};
// Go into first element of array and get AccountId value
var id = _.get(OnlineList[0], "AccountId");
// Convert value to int
var int = parseInt(id,10);
// Pass into function that gets AccountName from AccountId and replaces AccountId in that element of OnlineList array
getAccountName(int);
//result
console.log(OnlineUsers);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Overall I want my code to function like this:
Upvotes: 1
Views: 110
Reputation: 713
The question has been answered but I have a different solution I would like to share.
I recently created a library that does array categorization in JavaScript, called categorize
.
Here is what would be the solution using it:
const { categorize } = require("categorize");
const onlineList = [
{
"Role": "Adjuster",
"AccountId": "4",
"UserId": "1e72d58e",
"DisplayName": "Big Bob",
},
{
"Role": "Adviser",
"AccountId": "5",
"UserId": "a0daba73",
"DisplayName": "Sassy Sally",
}
];
const categories = [
{ name: "Dealership", filter: ({ AccountId }) => AccountId === "4" },
{ name: "ClaimsCo", filter: ({ AccountId }) => AccountId === "5" },
];
const onlineUsers = categorize(onlineList, categories);
The onlineUsers
variable will contain this object:
{
"Dealership": [
{
"Role": "Adjuster",
"AccountId": "4",
"UserId": "1e72d58e",
"DisplayName": "Big Bob"
}
],
"ClaimsCo": [
{
"Role": "Adviser",
"AccountId": "5",
"UserId": "a0daba73",
"DisplayName": "Sassy Sally"
}
]
}
Upvotes: 1
Reputation: 192287
You need to map and replace AccountId
number with the name, and then group by the name. I use _.flow()
to create a pipeline:
const { flow, partialRight: pr, map, groupBy } = _;
// Simulates a get by Id API service
const accountService = (id) => id === 4 ? "ClaimsCo." : "Dealership";
const fn = flow(
pr(map, o => ({ ...o, AccountId: accountService(+o.AccountId) })), // replace AccountId with name the + operator converts to number
pr(groupBy, 'AccountId'), // group by the new AccountId
)
const OnlineList = [{"Role":"Adjuster","AccountId":"4","UserId":"1e72d58e","DisplayName":"Big Bob"},{"Role":"Adviser","AccountId":"5","UserId":"a0daba73","DisplayName":"Sassy Sally"}];
//result
const OnlineUsers = fn(OnlineList);
console.log(OnlineUsers);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
And the terser version using lodash/fp:
const { flow, map, groupBy } = _;
// Simulates a get by Id API service
const accountService = (id) => id === 4 ? "ClaimsCo." : "Dealership";
const fn = flow(
map(o => ({ ...o, AccountId: accountService(+o.AccountId) })), // replace AccountId with name the + operator converts to number
groupBy('AccountId'), // group by the new AccountId
)
const OnlineList = [{"Role":"Adjuster","AccountId":"4","UserId":"1e72d58e","DisplayName":"Big Bob"},{"Role":"Adviser","AccountId":"5","UserId":"a0daba73","DisplayName":"Sassy Sally"}];
//result
const OnlineUsers = fn(OnlineList);
console.log(OnlineUsers);
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
Upvotes: 1
Reputation: 51
// loaded from API Request into array
var OnlineList = [];
// Sorted and ordered for display
var OnlineUsers = [];
OnlineList = [{
"Role": "Adjuster",
"AccountId": "4",
"UserId": "1e72d58e",
"DisplayName": "Big Bob",
},
{
"Role": "Adviser",
"AccountId": "5",
"UserId": "a0daba73",
"DisplayName": "Sassy Sally",
}
];
// GroupBy function: https://stackoverflow.com/questions/14446511/most-efficient-method-to-groupby-on-an-array-of-objects/43215522
let groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
// Simulates a get by Id API service
let accountService = (id) => {
if (id == 4) {
return "ClaimsCo."
} else {
return "Dealership"
}
}
// pass in AccountId
let getAccountName = function(int, element) {
var accountName = "";
//get AccountName from Id
accountName = accountService(int);
// check for AccountId
if (OnlineList[element].hasOwnProperty('AccountId')) {
// Set AccountId value to AccountName
OnlineList[element].AccountId = accountName;
// Group results and set to OnlineUsers array
OnlineUsers = groupBy(OnlineList, 'AccountId');
}
};
for (var x = 0; x < OnlineList.length; x++) {
var id = _.get(OnlineList[x], "AccountId");
var int = parseInt(id, 10);
getAccountName(int, x);
}
// Go into first element of array and get AccountId value
//result
console.log(OnlineUsers);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
I had to pass the count from my for loop into my getAccountName function. Now it works as it should. Hope this helps somebody.
Upvotes: 1