如何在Javascript / Jquery中基于多个键对数组项进行分组

3

我有一个如下的JavaScript数组

var data = [{
            "Ticket_id": "239248",
            "Order_Issue": "SAP",
            "Region": "EU",
            "Line_No": "10",
            "Line_Issue": "Qty not available",
            "Serial_Number": "72CEP92"
        },
        {
            "Ticket_id": "239248",
            "Order_Issue": "SAP",
            "Region": "EU",
            "Line_No": "20",
            "Line_Issue": "contact info missing",
            "Serial_Number": "2198IE3"
        }];

我想按多个键对我的数组进行分组。结果应如下所示:
var data = [{
            "Ticket_id": "239248",
            "Order_Issue": "SAP",
            "Region": "EU",
            "Lines" : [ 
            {"Line_No": "10",
            "Line_Issue": "Qty not available",
            "Serial_Number": "72CEP92"},
            {"Line_No": "20",
            "Line_Issue": "contact info missing",
            "Serial_Number": "2198IE3"}]
        }];

基本上,我会按照Ticket_id、Order_Issue和Region进行分组。然后,我会添加一个Items子数组,其中我将存储所有的Line_No、Line_Issue和Serial_Number。

I succeeded to group only by one key let's say by Ticket_id as the below example. When I add another key to my object obj[item."Order_Issue] = obj[item."Order_Issue] || [];, the group by will be done only on that key and ignore the previous key. Any suggestions please what am I doing wrong and how to get the exact format I want. Thank you.

var data = [{
            "Ticket_id": "239248",
            "Order_Issue": "SAP",
            "Region": "EU",
            "Line_No": "10",
            "Line_Issue": "Qty not available",
            "Serial_Number": "72CEP92"
        },
        {
            "Ticket_id": "239248",
            "Order_Issue": "SAP",
            "Region": "EU",
            "Line_No": "20",
            "Line_Issue": "contact info missing",
            "Serial_Number": "2198IE3"
        },
        {
            "Ticket_id": "239267",
            "Order_Issue": "Online Payment",
            "Region": "EU",
            "Line_No": "10",
            "Line_Issue": "card expired",
            "Serial_Number": "21BBF03"
        }];
        
 var group_Line_No = data.reduce(function (obj, item) {
    obj[item.Ticket_id] = obj[item.Ticket_id] || [];
    obj[item.Ticket_id].push(item.Line_No);
    return obj;
}, {});

console.log(group_Line_No);

var groups = Object.keys(group_Line_No).map(function (key) {
    return {Ticket_id: key, Line_No: group_Line_No[key]};
});

console.log(groups);

3个回答

4
如果你想要一个针对任意键的动态解决方案,你可以使用reduce方法,并在内部使用for...of循环来检查当前属性是否是分组的关键字或应该添加到Lines数组中的新对象中。

var data = [{"Ticket_id":"239248","Order_Issue":"SAP","Region":"EU","Line_No":"10","Line_Issue":"Qty not available","Serial_Number":"72CEP92"},{"Ticket_id":"239248","Order_Issue":"SAP","Region":"EU","Line_No":"20","Line_Issue":"contact info missing","Serial_Number":"2198IE3"},{"Ticket_id":"239267","Order_Issue":"Online Payment","Region":"EU","Line_No":"10","Line_Issue":"card expired","Serial_Number":"21BBF03"}]

const groupBy = keys => data.reduce((r, e) => {
  const key = keys.map(k => e[k]).join('|');
  const obj = {}

  for (let [k, v] of Object.entries(e)) {
    if (!r[key]) r[key] = {Lines: []}

    if (keys.includes(k)) {
      r[key][k] = v
    } else {
      obj[k] = v
    }
  }

  r[key].Lines.push(obj)
  return r;
}, {});

const result = groupBy(['Ticket_id', 'Order_Issue', 'Region'])
console.log(Object.values(result))


2
使用类似的方法,但将所有关键属性合并到中间结果对象的键中。

var data = [{
    "Ticket_id": "239248",
    "Order_Issue": "SAP",
    "Region": "EU",
    "Line_No": "10",
    "Line_Issue": "Qty not available",
    "Serial_Number": "72CEP92"
  },
  {
    "Ticket_id": "239248",
    "Order_Issue": "SAP",
    "Region": "EU",
    "Line_No": "20",
    "Line_Issue": "contact info missing",
    "Serial_Number": "2198IE3"
  },
  {
    "Ticket_id": "239267",
    "Order_Issue": "Online Payment",
    "Region": "EU",
    "Line_No": "10",
    "Line_Issue": "card expired",
    "Serial_Number": "21BBF03"
  }
];

var group_Line_No = data.reduce(function(obj, item) {
  let key = `${item.Ticket_id}.${item.Order_Issue}.${item.Region}`;
  obj[key] = obj[key] || {
    Ticket_id: item.Ticket_id,
    Order_Issue: item.Order_Issue,
    Region: item.Region,
    Lines: []
  };
  obj[key].Lines.push({
    Line_No: item.Line_No,
    Line_Issue: item.Line_Issue,
    Serial_Number: item.Serial_Number
  });
  return obj;
}, {});

var groups = Object.values(group_Line_No);

console.log(groups);


1
你走在正确的道路上。 当处理一个条目时,你可以通过组合“Ticket_id”、“Order_Issue”和“Region”来创建一个id,然后将该行数据推送。

const groupEntries = arr =>
  Object.values(
    arr.reduce(
      (
        obj,
        { Ticket_id, Order_Issue, Region, Line_No, Line_Issue, Serial_Number }
      ) => {
        const id = [Ticket_id, Order_Issue, Region].join('#') // unique id
        obj[id] = obj[id] || { Ticket_id, Order_Issue, Region, Lines: [] }
        obj[id].Lines.push({ Line_No, Line_Issue, Serial_Number }) // push new line data
        return obj
      },
      {}
    )
  )
  
const data = [
  {
    Ticket_id: '239248',
    Order_Issue: 'SAP',
    Region: 'EU',
    Line_No: '10',
    Line_Issue: 'Qty not available',
    Serial_Number: '72CEP92',
  },
  {
    Ticket_id: '239248',
    Order_Issue: 'SAP',
    Region: 'EU',
    Line_No: '20',
    Line_Issue: 'contact info missing',
    Serial_Number: '2198IE3',
  },
  {
    Ticket_id: '239267',
    Order_Issue: 'Online Payment',
    Region: 'EU',
    Line_No: '10',
    Line_Issue: 'card expired',
    Serial_Number: '21BBF03',
  },
]

const result = groupEntries(data)

console.log(result)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接