首页 > 解决方案 > 使用 GroupBy 和 lodash 尝试正确格式化我的数组时遇到问题

问题描述

我想获取用户列表并将它们分类到一个新数组中以由我的应用程序呈现。

我得到了什么:

OnlineList = [
  {
    "Role": "Adjuster",
    "AccountId": "4",
    "UserId": "1e72d58e",
    "DisplayName": "Big Bob",
  },
  {
    "Role": "Adviser",
    "AccountId": "5",
    "UserId": "a0daba73",
    "DisplayName": "Sassy Sally",
  }
];

我想要什么结果:

OnlineUsers = {
  "Dealership": [
    {
      "Role": "Adviser",
      "AccountId": "Dealership",
      "UserId": "a0daba73",
      "DisplayName": "Sassy Sally",
    }
  ],
  "ClaimsCo": [
    {
      "Role": "Adjuster",
     "AccountId": "ClaimsCo",
      "UserId": "1e72d58e",
      "DisplayName": "Big Bob",
    }
  ]
}

结果我得到:

OnlineUsers = {
  "5": [    <----------- Problem
    {
      "Role": "Adviser",
      "AccountId": "5",   <----------- Problem
      "UserId": "a0daba73",
      "DisplayName": "Sassy Sally",
    }
  ],
  "ClaimsCo": [
    {
      "Role": "Adjuster",
      "AccountId": "Dealership",
      "UserId": "1e72d58e",
      "DisplayName": "Big Bob",
    }
  ]
}

这是我设置的复制问题的 JFiddle:http: //jsfiddle.net/vc4mjwx3/20/

我的代码:

// 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>

总的来说,我希望我的代码能够像这样运行:

  1. 遍历 OnlineList 中的每个元素
  2. 对于该元素,获取 AccountId 值
  3. 将该 AccountId 值传递给将返回 AccountName 的服务
  4. 将该元素的 AccountId 替换为 AccountName
  5. 对 OnlineList 数组中的所有其他元素重复
  6. 处理完所有 AccountId/AccountName 后,使用 GroupBy 按 AccountId 属性对 OnlineList 数组的所有元素进行分组,并将它们设置为名为 OnlineUsers 的新数组。

标签: javascriptarrayslodash

解决方案


问题已得到解答,但我想分享一个不同的解决方案。

我最近创建了一个在 JavaScript 中进行数组分类的库,名为categorize.

以下是使用它的解决方案:

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);

onlineUsers 变量将包含此对象:

{
  "Dealership": [
    {
      "Role": "Adjuster",
      "AccountId": "4",
      "UserId": "1e72d58e",
      "DisplayName": "Big Bob"
    }
  ],
  "ClaimsCo": [
    {
      "Role": "Adviser",
      "AccountId": "5",
      "UserId": "a0daba73",
      "DisplayName": "Sassy Sally"
    }
  ]
}

推荐阅读