Search code examples
javascripttypescriptlinqgroup-bylinq.js

linqts - group by multiple properties


I have an array of JSON objects which have to be grouped by multiple properties.

const JSON_DATA = [
        {"componentName":"CP1","articleNumber":"441","componentType":"Ext","version":"V1.1.6"},
        {"componentName":"CP5","articleNumber":"444","componentType":"Int","version":"V2.1.8"},
        {"componentName":"CP5","articleNumber":"444","componentType":"Ext","version":"V2.1.0"},
        {"componentName":"CP5","articleNumber":"444","componentType":"Ext","version":"V2.1.8"},
        {"componentName":"CP4","articleNumber":"442","componentType":"Ext","version":"V1.1.0"}];

I'd like to use linqts to group by componentName, articleNumber and componentType.

interface IComponent {
  componentName: String;
  articleNumber: String;
  componentType: String;
  version: String;
}

class JsonGroupBy {
  public groupBy(data: IComponent[]): any {
    let mylist = new List < IComponent > (data);

    let result = mylist.GroupBy((comp) => comp.componentName, (comp) => comp.version);

    return result;
  }
}

This is working but I can't figure out how to group not only by componentName but also by articleNumber and componentType. The current output looks like this:

{"CP1": ["V1.1.6"], "CP4": ["V1.1.0"], "CP5": ["V2.1.8", "V2.1.0", "V2.1.8"]}

My prefered result would be like this:

   
  [
    {"componentName": "CP1","articleNumber":"441","componentType":"Ext","version": ["V1.1.6"]},
    {"componentName": "CP5","articleNumber":"444","componentType":"Int","version": ["V2.1.8"]},
    {"componentName": "CP5","articleNumber":"444","componentType":"Ext","version": ["V2.1.0","2.1.8"]},
    {"componentName": "CP4","articleNumber":"442","componentType":"Ext","version": ["V1.1.0"]}
]


Solution

  • You could collect the version and build a new data set for each group.

    const
        JSON_DATA = [{ componentName: "CP1", articleNumber: "441", componentType: "Ext", version: "V1.1.6" }, { componentName: "CP5", articleNumber: "444", componentType: "Int", version: "V2.1.8" }, { componentName: "CP5", articleNumber: "444", componentType: "Ext", version: "V2.1.0" }, { componentName: "CP5", articleNumber: "444", componentType: "Ext", version: "V2.1.8" }, { componentName: "CP4", articleNumber: "442", componentType: "Ext", version: "V1.1.0" }],
        result = Enumerable
            .From(JSON_DATA)
            .GroupBy(
                null,
                "$.version",
                "{ componentName: $.componentName, articleNumber: $.articleNumber, componentType: $.componentType, version: $$.ToArray() }",
                "[$.componentName, $.articleNumber, $.componentType].join('|')"
            )
            .ToArray();
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>