Lodash group by multiple properties if property value is true

前端 未结 8 1904
执笔经年
执笔经年 2020-12-10 02:20

I have an array of vehicles that need to be grouped by make and model, only if the \'selected\' property is true. The resulting object should contain properties for make mod

相关标签:
8条回答
  • 2020-12-10 02:37

    Grouping and filtering an object or array without LODASH on pure JS:

    // Группировка и фильтрация объекта или массива без LODASH на чистом JS:
    let k = "HUID", // group by; 
    input = [
    {HUID:11,test:1},
    {HUID:11,test:111},
    {HUID:'eeeeeeeeeeee',test:11111},
    {HUID:22,test:2},
    {HUID:33,test:3}
    ],
    result = input.reduce((map, obj) => { 
    //if(!obj.selected) { return map; } 
    let makeCode = (map[obj[k]] = map[obj[k]] || {}); // var modelCode = makeCode[obj.HUID] = makeCode[obj.HUID] || { count: 0 }; 
    let l = map[obj[k]],
        m = Object.keys(l).length; 
    l[m] = { ...obj }; 
    return map; 
    }, {} );
    console.log(result);

    Copied from VK

    0 讨论(0)
  • 2020-12-10 02:43

    const result = _.chain(vehicles)
    .filter('selected')
    .groupBy('makeCode')
    .mapValues(values => _.chain(values)
        .groupBy('modelCode')
        .mapValues(_.size)
        .value()
    )
    .value()

    0 讨论(0)
  • 2020-12-10 02:45

    Following code works if you focus on result:

    inmy case, 'Brand' and 'Item Code' are properties

                const products = _.groupBy(this.productsTable.data, (item) => {
                    return [item['Brand'], item['Item Code']];
                });
    
    0 讨论(0)
  • 2020-12-10 02:49

    Since you're already using lodash, you can take advantage of the _.filter function. This will return only the items where selected is true.

    var selectedVehicles = _.filter(response.vehicleTypes, 'selected');
    

    Now that you have the selectedVehicles array, you can use your original code for grouping by the makeCode.

    selectedVehicles = _.groupBy(selectedVehicles, function(item) {
      return item.makeCode;
    });
    

    This returns an object, so we will need to iterate through those keys, and perform our second groupBy

    _.forEach(selectedVehicles, function(value, key) {
      selectedVehicles[key] = _.groupBy(selectedVehicles[key], function(item) {
        return item.modelCode;
      });
    });
    

    From this you will have an object of the form. I'll leave it to you to get the count from each array.

    { 'Make-A': { 'Model-a': [ ... ] },
      'Make-B': { 'Model-c': [ ... ] },
      'Make-C': { 'Model-b': [ ..., ... ] } }
    
    0 讨论(0)
  • 2020-12-10 02:52

    const multiGroupBy = (array, group, ...restGroups) => {
      if(!group) {
        return array;
      }
      const currGrouping = _.groupBy(array, group);
      if(!restGroups.length) {
        return currGrouping;
      }
      return _.transform(currGrouping, (result, value, key) => {
        result[key] = multiGroupBy(value, ...restGroups);
      }, {});
    };
    
    console.log(multiGroupBy([{x:1,y:1,z:1},{x:1,y:2,z:1},{x:2,y:1,z:1},{x:2,y:2,z:1},{x:1,y:1,z:2},{x:1,y:2,z:2},{x:2,y:1,z:2},{x:2,y:2,z:2}],'x','y'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

    or if you prefer old syntax

    function multiGroupBy(array, group) {
      if(!group) {
        return array;
      }
      var currGrouping = _.groupBy(array, group);
      var restGroups = Array.prototype.slice.call(arguments);
      restGroups.splice(0,2);
      if(!restGroups.length) {
        return currGrouping;
      }
      return _.transform(currGrouping, function(result, value, key) {
        result[key] = multiGroupBy.apply(null, [value].concat(restGroups));
      }, {});
    }
    
    console.log(multiGroupBy([{x:1,y:1,z:1},{x:1,y:2,z:1},{x:2,y:1,z:1},{x:2,y:2,z:1},{x:1,y:1,z:2},{x:1,y:2,z:2},{x:2,y:1,z:2},{x:2,y:2,z:2}],'x','y'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

    0 讨论(0)
  • 2020-12-10 02:54

    I am not sure if this will solve Your problem, but in group_by You can add custom logic which allow You to create composite key.

    Remember that SEPERATOR value should be defined accordingly to data source You work with, if "--" characters occur in model or type You should not used them as it will not allow You to reverse the process of grouping.

    const SEPERATOR = "--";
    _.chain(data).filter((item) => item.selected).groupBy((item)=>`${item.model}${SEPERATOR}${item.type}`).value();
    
    0 讨论(0)
提交回复
热议问题