简体   繁体   English

同级别对象的组数组

[英]Group Array of Objects of same level

I have an array which has different level of approvers.我有一个具有不同级别批准者的数组。 I need to combine the object of similar level and group them with the Name+counter.我需要组合相似级别的对象并将它们与名称+计数器分组。

"APPROVERS": [
        {
            "LEVEL": "L5",
            "EMAIL": "FTEST@TEST.COM",
            "FULLNAME": "FNAME",
            "POSITION": "FPOS",
            "SLA": "48",
            "STATUS": "INITIAL"
        },
        {
            "LEVEL": "L4",
            "EMAIL": "JTEST@TEST.COM",
            "FULLNAME": "JNAME",
            "POSITION": "JPOS",
            "SLA": "48",
            "STATUS": "INITIAL"
        },
        {
            "LEVEL": "L5",
            "EMAIL": "LTEST@TEST.COM",
            "FULLNAME": "LNAME",
            "POSITION": "GPOS",
            "SLA": "48",
            "STATUS": "INITIAL"
        },
        {
            "LEVEL": "L5",
            "EMAIL": "TTEST@TEST.COM",
            "FULLNAME": "TNAME",
            "POSITION": "CPOS",
            "SLA": "48",
            "STATUS": "INITIAL"
        }  
    ]

I need to combine the objects of same level into one and provide the unique name.我需要将相同级别的对象合并为一个并提供唯一名称。

 "APPROVERS": [
        {
            "LEVEL": "L5",
            "EMAIL1": "FTEST@TEST.COM",
            "FULLNAME1": "FNAME",
            "POSITION1": "FPOS",
            "SLA1": "48",
            "STATUS1": "INITIAL",
            "EMAIL2": "LTEST@TEST.COM",
            "FULLNAME2": "LNAME",
            "POSITION2": "GPOS",
            "SLA2": "48",
            "STATUS2": "INITIAL",
            "EMAIL3": "TTEST@TEST.COM",
            "FULLNAME3": "TNAME",
            "POSITION3": "CPOS",
            "SLA3": "48",
            "STATUS3": "INITIAL"
        },
        {
            "LEVEL": "L4",
            "EMAIL": "JTEST@TEST.COM",
            "FULLNAME": "JNAME",
            "POSITION": "JPOS",
            "SLA": "48",
            "STATUS": "INITIAL"
        } 
    ]

I tried only to combine EMAIL by looping the array but not able to achieve the result.Kindly suggest.我只尝试通过循环数组来组合 EMAIL,但无法实现结果。请建议。

var result = [];
    var i=0
    APPROVERS.forEach(function(obj) {
      var id = obj.LEVEL
      if(!this[id]) result.push(this[id] = obj);
      else this[id].EMAIL += obj.EMAIL+i;
      i++;
    }, Object.create(null));

    console.log(result)

You can do this by grouping the elements of the same level in an object associating levels with an array of elements, like so:您可以通过将级别与元素数组关联的对象中的同一级别的元素进行分组来完成此操作,如下所示:

{
  "L5": [
    {
      "EMAIL": "FTEST@TEST.COM",
      "FULLNAME": "FNAME",
      "POSITION": "FPOS",
      "SLA": "48",
      "STATUS": "INITIAL"
    },
    ...
  ],
  "L4": [
    {
      "EMAIL": "JTEST@TEST.COM",
      "FULLNAME": "JNAME",
      "POSITION": "JPOS",
      "SLA": "48",
      "STATUS": "INITIAL"
    }
  ]
}

Then iterate over the levels and create an array of unique levels which hold each elements with their unique set of keys EMAIL{i} , FULLNAME{i} , POSITION{i} , SLA{i} and STATUS{i} :然后迭代这些级别并创建一个唯一级别的数组,这些级别包含每个元素及其唯一的键EMAIL{i}FULLNAME{i}POSITION{i}SLA{i}STATUS{i}

[
  {
    "LEVEL": "L5",
    "EMAIL1": "FTEST@TEST.COM",
    "FULLNAME1": "FNAME",
    "POSITION1": "FPOS",
    "SLA1": "48",
    "STATUS1": "INITIAL",
    ...
  },
  {
    "LEVEL": "L4",
    "EMAIL1": "JTEST@TEST.COM",
    "FULLNAME1": "JNAME",
    "POSITION1": "JPOS",
    "SLA1": "48",
    "STATUS1": "INITIAL"
  }
]

Here is the full code:这是完整的代码:

 // prepare an intermediate representation of your data { level => approver[] } const grouped = data['APPROVERS'].reduce((approvers, approver) => { const { LEVEL, ...props } = approver; approvers[LEVEL] = approvers[LEVEL] ? approvers[LEVEL].concat([props]) : [props] return approvers; }, {}) // helper function to append a suffix to all keys of a given object const suffixKeys = (obj, suffix) => { return Object.entries(obj).reduce((result, [key, value]) => { return { ...result, [key+suffix]: value } }, {}); } // combine the objects into an array using the intermediate representation const result = Object.entries(grouped).map(([name, group]) => { return group.reduce((grouped, current, i) => { return { ...grouped, ...suffixKeys(current, i+1) } }, { LEVEL: name }); }); console.log(result)
 <script>const data={APPROVERS:[{LEVEL:"L5",EMAIL:"FTEST@TEST.COM",FULLNAME:"FNAME",POSITION:"FPOS",SLA:"48",STATUS:"INITIAL"},{LEVEL:"L4",EMAIL:"JTEST@TEST.COM",FULLNAME:"JNAME",POSITION:"JPOS",SLA:"48",STATUS:"INITIAL"},{LEVEL:"L5",EMAIL:"LTEST@TEST.COM",FULLNAME:"LNAME",POSITION:"GPOS",SLA:"48",STATUS:"INITIAL"},{LEVEL:"L5",EMAIL:"TTEST@TEST.COM",FULLNAME:"TNAME",POSITION:"CPOS",SLA:"48",STATUS:"INITIAL"}]};</script>

However, in my opinion, the intermediate format would be a lot easier to work with.但是,在我看来,中间格式会更容易使用。

By putting the tag lodash I guess you don't mind using it.通过放置标签lodash我猜你不介意使用它。 I'm not sure you understand it, but I've tried my best to balance between succinctness and readability .我不确定你是否理解它,但我已尽力在简洁性和可读性之间取得平衡

 function groupByLevel(approvers) { const group = _.groupBy(approvers, 'LEVEL'); // console.log(group); // try logging to see what we have return Object.entries(group).map( ([LEVEL, array]) => { return array.reduce((acc, cur, idx) => ({ ...acc, ['EMAIL' + (idx + 1)]: cur.EMAIL , ['FULLNAME' + (idx + 1)]: cur.FULLNAME , ['POSITION' + (idx + 1)]: cur.POSITION , ['SLA' + (idx + 1)]: cur.SLA , ['STATUS' + (idx + 1)]: cur.STATUS , }), { LEVEL }); }) } var APPROVERS = [ { LEVEL: 'L5', EMAIL: 'FTEST@TEST.COM', FULLNAME: 'FNAME', POSITION: 'FPOS', SLA: '48', STATUS: 'INITIAL' }, { LEVEL: 'L4', EMAIL: 'JTEST@TEST.COM', FULLNAME: 'JNAME', POSITION: 'JPOS', SLA: '48', STATUS: 'INITIAL' }, { LEVEL: 'L5', EMAIL: 'LTEST@TEST.COM', FULLNAME: 'LNAME', POSITION: 'GPOS', SLA: '48', STATUS: 'INITIAL' }, { LEVEL: 'L5', EMAIL: 'TTEST@TEST.COM', FULLNAME: 'TNAME', POSITION: 'CPOS', SLA: '48', STATUS: 'INITIAL' } ] console.log(groupByLevel(APPROVERS))
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

The following algorithm achieves exactly what you want:以下算法完全符合您的要求:

 let APPROVERS = [ { "LEVEL": "L5", "EMAIL": "FTEST@TEST.COM", "FULLNAME": "FNAME", "POSITION": "FPOS", "SLA": "48", "STATUS": "INITIAL" }, { "LEVEL": "L4", "EMAIL": "JTEST@TEST.COM", "FULLNAME": "JNAME", "POSITION": "JPOS", "SLA": "48", "STATUS": "INITIAL" }, { "LEVEL": "L5", "EMAIL": "LTEST@TEST.COM", "FULLNAME": "LNAME", "POSITION": "GPOS", "SLA": "48", "STATUS": "INITIAL" }, { "LEVEL": "L5", "EMAIL": "TTEST@TEST.COM", "FULLNAME": "TNAME", "POSITION": "CPOS", "SLA": "48", "STATUS": "INITIAL" } ]; var result = {}; var compareLevel = {}; for (let index = 0; index < APPROVERS.length; index++) { if(Object.keys(compareLevel).includes(APPROVERS[index].LEVEL)){ for (const key in APPROVERS[index]) { if(key == 'LEVEL') continue; let keyIndex = compareLevel[APPROVERS[index].LEVEL] + 1; result[APPROVERS[index].LEVEL][key + keyIndex] = APPROVERS[index][key]; } compareLevel[APPROVERS[index].LEVEL]++; }else{ result[APPROVERS[index].LEVEL] = APPROVERS[index]; compareLevel[APPROVERS[index].LEVEL] = 1; } } let resultArr = Object.values(result); console.log(Object.values(result));

I see that there are a lot of good answer here (that i will upvote), but as i promised, i deliver to you how i would taclke your problem.我看到这里有很多好的答案(我会赞成),但正如我所承诺的,我会告诉你我将如何解决你的问题。 Let me show the code让我展示一下代码

var theApprovers =  [
    {
        "LEVEL": "L5",
        "EMAIL": "FTEST@TEST.COM",
        "FULLNAME": "FNAME",
        "POSITION": "FPOS",
        "SLA": "48",
        "STATUS": "INITIAL"
    },
    {
        "LEVEL": "L4",
        "EMAIL": "JTEST@TEST.COM",
        "FULLNAME": "JNAME",
        "POSITION": "JPOS",
        "SLA": "48",
        "STATUS": "INITIAL"
    },
    {
        "LEVEL": "L5",
        "EMAIL": "LTEST@TEST.COM",
        "FULLNAME": "LNAME",
        "POSITION": "GPOS",
        "SLA": "48",
        "STATUS": "INITIAL"
    },
    {
        "LEVEL": "L5",
        "EMAIL": "TTEST@TEST.COM",
        "FULLNAME": "TNAME",
        "POSITION": "CPOS",
        "SLA": "48",
        "STATUS": "INITIAL"
    }  
]

function groupBy (collection, key) { // based on https://stackoverflow.com/a/34890276/903998
  return collection.reduce(function(grouped, element) {
    (grouped[element[key]] = grouped[element[key]] || []).push(element);
    return grouped;
  }, {});
};

function arrangeApprovers(approvers) {
  // first group by level
  var groupedByLevel = groupBy(approvers,"LEVEL")
  // then for each level do the arrange as you need
  var arrayOflevelWithApprovers = Object.keys(groupedByLevel).map(function(level) {
    var approversOfSameLevel = groupedByLevel[level]
    var levelWithApprovers = {"LEVEL" : level}
    approversOfSameLevel.forEach(function(approber, index) {
      var suffixNumber = index+1
      levelWithApprovers["EMAIL"+suffixNumber] = approber["EMAIL"]
      levelWithApprovers["FULLNAME"+suffixNumber] = approber["FULLNAME"]
      levelWithApprovers["POSITION"+suffixNumber] = approber["POSITION"]
      levelWithApprovers["SLA"+suffixNumber] = approber["SLA"]
      levelWithApprovers["STATUS"+suffixNumber] = approber["STATUS"]
    })
    return levelWithApprovers
  });
  return arrayOflevelWithApprovers;
}

var theApproversArrenged = arrangeApprovers(theApprovers) // so they are arrangen in the convenient fashion..
console.log(theApproversArrenged)

https://repl.it/repls/TruthfulLivelyInterface https://repl.it/repls/TruthfulLivelyInterface

You could see that inside theAprroversArrenged the elements are arranged in the fashion you need.您可以看到在theAprroversArrenged ,元素以您需要的方式排列。

Disclaimer do note that for level4 (and for those levels with an unique approver) the generated records will refer to his attributes with the suffix of 1. Hope that to not be something really annoying for your purposes.免责声明请注意,对于 level4(以及具有唯一批准者的那些级别),生成的记录将引用后缀为 1 的他的属性。希望这不会对您的目的造成真正的困扰。

After you group the array by LEVEL , you can map the groups.LEVEL对数组进行分组后,您可以映射这些组。 Check the group's length.检查组的长度。 If it has a single item, you can return that item.如果它只有一个项目,您可以退回该项目。 If it has more than 1 one, you'll need to map the items, and map the keys of the items to include the item's index + 1, and then merge all items to a single object:如果超过 1 个,则需要映射项目,并将项目的键映射为包含项目的索引 + 1,然后将所有项目合并为单个对象:

 const fn = (arr, groupKey) => { const groups = _.groupBy(arr, groupKey); return _.map(groups, group => group.length > 1 ? // if there's more than one item _.merge(... // merge all items _.map(group, (item, idx) => _.mapKeys( // map the items in the group item, (v, k) => k === groupKey ? k : `${k}${idx + 1}` // add the index to all keys, but LEVEL )) ) : group[0] ) }; const data = {APPROVERS:[{LEVEL:"L5",EMAIL:"FTEST@TEST.COM",FULLNAME:"FNAME",POSITION:"FPOS",SLA:"48",STATUS:"INITIAL"},{LEVEL:"L4",EMAIL:"JTEST@TEST.COM",FULLNAME:"JNAME",POSITION:"JPOS",SLA:"48",STATUS:"INITIAL"},{LEVEL:"L5",EMAIL:"LTEST@TEST.COM",FULLNAME:"LNAME",POSITION:"GPOS",SLA:"48",STATUS:"INITIAL"},{LEVEL:"L5",EMAIL:"TTEST@TEST.COM",FULLNAME:"TNAME",POSITION:"CPOS",SLA:"48",STATUS:"INITIAL"}]}; const result = fn(data.APPROVERS, 'LEVEL') console.log(result)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Vanilla JS 中对象数组的多级组 - Multi level group on array of objects in Vanilla JS 对数组对象进行分组,以使具有相似键的对象不会放入同一组 - Group array objects so that objects with similar key are not put into the same group 如何按值对同一项目的对象数组进行分组? - How to group an array of objects by value for the same item? javascript中具有相同键的组数组对象不起作用 - Group array objects with same key in javascript is not working 如何按名称相似但不相同的对象数组进行分组 - How to group by an array of objects with similar names but not the same 在对象数组中使用相同的键对值进行分组 - Group values with the same key in an array of objects 如何将相同类型的值与两级对象数组相加? - How to sum value of the same type with two level array of objects? AngularJS - 将具有相同值的数组中的对象分组到新数组中 - AngularJS - Group objects in an array with a same value into a new array 将格式化的 json object 转换为同一级别的对象数组(展平)并在每个级别上求和 - converting formatted json object to array of objects on the same level (flatten) and sum up on each level 如何通过相同的值和某些属性对对象数组进行联合/分组? - How to union/group array of objects by same values and by some property?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM