Home > Net >  How do I have a nested grouping in react js?
How do I have a nested grouping in react js?

Time:03-29

I Have this array:

[
{id: 6,  deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId:3,deductionExchangeTypeTitle: "Exchange1" ,wageTitle:"wageTitle1"}
 {id: 8,  deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId: 3deductionExchangeTypeTitle: "Exchange1",wageTitle:"wageTitle2"}
 {id: 4,  deductionTypeId: 1, deductionTypeTitle:"TypeTitle2",deductionExchangeTypeId: 4,deductionExchangeTypeTitle: "Exchange2",wageTitle:"wageTitle3"}
 {id: 5,  deductionTypeId: 1, deductionTypeTitle:"TypeTitle2",deductionExchangeTypeId: 5, deductionExchangeTypeTitle: "Exchange3",wageTitle:"wageTitle4"}
 {id: 9,  deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId: 3 ,deductionExchangeTypeTitle: "Exchange1",wageTitle:"wageTitle5"}
 {id: 10, deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId: 3,deductionExchangeTypeTitle: "Exchange1",wageTitle:"wageTitle6"}
 {id: 11, deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId: 3,deductionExchangeTypeTitle: "Exchange1",wageTitle:"wageTitle7"}
 {id: 12, deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId: 3,deductionExchangeTypeTitle: "Exchange1",wageTitle:"wageTitle8"}]

And I want to grouping it in react js like this

 -TypeTitle1  
   -Exchange1
      .wageTitle1
      .wageTitle2
      .wageTitle6
      .wageTitle7
      .wageTitle8
 -TypeTitle2 
   -Exchange2
       .wageTitle3   
   -Exchange3
       .wageTitle4

CodePudding user response:

You could use Lodash to transform your data using groupBy, mapValues, and flatMap.

import _ from 'lodash';

const data = [
  {
    id: 6,
    deductionTypeId: 6,
    deductionTypeTitle: 'TypeTitle1',
    deductionExchangeTypeId: 3,
    deductionExchangeTypeTitle: 'Exchange1',
    wageTitle: 'wageTitle1',
  },
  {
    id: 8,
    deductionTypeId: 6,
    deductionTypeTitle: 'TypeTitle1',
    deductionExchangeTypeId: 3,
    deductionExchangeTypeTitle: 'Exchange1',
    wageTitle: 'wageTitle2',
  },
  {
    id: 4,
    deductionTypeId: 1,
    deductionTypeTitle: 'TypeTitle2',
    deductionExchangeTypeId: 4,
    deductionExchangeTypeTitle: 'Exchange2',
    wageTitle: 'wageTitle3',
  },
  {
    id: 5,
    deductionTypeId: 1,
    deductionTypeTitle: 'TypeTitle2',
    deductionExchangeTypeId: 5,
    deductionExchangeTypeTitle: 'Exchange3',
    wageTitle: 'wageTitle4',
  },
  {
    id: 9,
    deductionTypeId: 6,
    deductionTypeTitle: 'TypeTitle1',
    deductionExchangeTypeId: 3,
    deductionExchangeTypeTitle: 'Exchange1',
    wageTitle: 'wageTitle5',
  },
  {
    id: 10,
    deductionTypeId: 6,
    deductionTypeTitle: 'TypeTitle1',
    deductionExchangeTypeId: 3,
    deductionExchangeTypeTitle: 'Exchange1',
    wageTitle: 'wageTitle6',
  },
  {
    id: 11,
    deductionTypeId: 6,
    deductionTypeTitle: 'TypeTitle1',
    deductionExchangeTypeId: 3,
    deductionExchangeTypeTitle: 'Exchange1',
    wageTitle: 'wageTitle7',
  },
  {
    id: 12,
    deductionTypeId: 6,
    deductionTypeTitle: 'TypeTitle1',
    deductionExchangeTypeId: 3,
    deductionExchangeTypeTitle: 'Exchange1',
    wageTitle: 'wageTitle8',
  },
];

const result = _(data)
  .groupBy('deductionTypeTitle')
  .mapValues((items) =>
    _(items)
      .groupBy('deductionExchangeTypeTitle')
      .mapValues((items) =>
        _(items)
          .flatMap((item) => item.wageTitle)
          .value(),
      )
      .value(),
  )
  .value();

// result:
// {
//   TypeTitle1: {
//     Exchange1: ['wageTitle1', 'wageTitle2', 'wageTitle5', 'wageTitle6', 'wageTitle7', 'wageTitle8'],
//   },
//   TypeTitle2: { Exchange2: ['wageTitle3'], Exchange3: ['wageTitle4'] },
// }

``

CodePudding user response:

This may be one possible solution to achieve the desired objective.

Code Snippet

If the UI is not needed, simply use the method: groupAndSort to obtain the desired array which will be sorted in the desired order.

const Thingy = ({data, ...props}) => {
  const groupAndSort = arr => (
    [...arr.map(x => ({...x}))]
    .map(x => ({...x, l1: "", l2: "", l3: ""}))
    .sort((a, b) => (
      a.deductionTypeTitle === b.deductionTypeTitle
      ? a.deductionExchangeTypeTitle === b.deductionExchangeTypeTitle
        ? a.wageTitle === b.wageTitle
          ? 1
          : a.wageTitle > b.wageTitle
            ? 1
            : -1
        : a.deductionExchangeTypeTitle > b.deductionExchangeTypeTitle
          ? 1
          : -1
      : a.deductionTypeTitle > b.deductionTypeTitle
        ? 1
        : -1
    ))
    .map(
      (x, i, a) => {
        if (i === 0) {
          return ({
            ...x,
            l1: x.deductionTypeTitle,
            l2: x.deductionExchangeTypeTitle,
            l3: x.wageTitle
          })
        } else {
          const t = {...x};
          if (x.deductionTypeTitle !== a[i-1].deductionTypeTitle) {
            t.l1 = x.deductionTypeTitle
          };
          if (x.deductionExchangeTypeTitle !== a[i-1].deductionExchangeTypeTitle) {
            t.l2 = x.deductionExchangeTypeTitle
          };
          if (x.wageTitle !== a[i-1].wageTitle) {
            t.l3 = x.wageTitle
          };
          return t;
        }
      }
    )
  );
  return(
    <div>
      <h4>Desired Display</h4>
      {
        groupAndSort(data)
        .map(
          ({l1, l2, l3}) => (
            <div>
              <div>{l1}</div>
              <div>&emsp; &emsp; {l2}</div>
              <div>&emsp; &emsp; &emsp; &emsp; {l3}</div>
            </div>
          )
        )
      }
      <br/><br/>
      <h4>Sorted-Grouped Data-Array</h4>
      {
        JSON.stringify(groupAndSort(data))
      }
    </div>
  );
};

const rawData = [{
  id: 6,
  deductionTypeId: 6,
  deductionTypeTitle: "TypeTitle1",
  deductionExchangeTypeId: 3,
  deductionExchangeTypeTitle: "Exchange1",
  wageTitle: "wageTitle1"
}, {
  id: 8,
  deductionTypeId: 6,
  deductionTypeTitle: "TypeTitle1",
  deductionExchangeTypeId: 3,
  deductionExchangeTypeTitle: "Exchange1",
  wageTitle: "wageTitle2"
}, {
  id: 4,
  deductionTypeId: 1,
  deductionTypeTitle: "TypeTitle2",
  deductionExchangeTypeId: 4,
  deductionExchangeTypeTitle: "Exchange2",
  wageTitle: "wageTitle3"
}, {
  id: 5,
  deductionTypeId: 1,
  deductionTypeTitle: "TypeTitle2",
  deductionExchangeTypeId: 5,
  deductionExchangeTypeTitle: "Exchange3",
  wageTitle: "wageTitle4"
}, {
  id: 9,
  deductionTypeId: 6,
  deductionTypeTitle: "TypeTitle1",
  deductionExchangeTypeId: 3,
  deductionExchangeTypeTitle: "Exchange1",
  wageTitle: "wageTitle5"
}, {
  id: 10,
  deductionTypeId: 6,
  deductionTypeTitle: "TypeTitle1",
  deductionExchangeTypeId: 3,
  deductionExchangeTypeTitle: "Exchange1",
  wageTitle: "wageTitle6"
}, {
  id: 11,
  deductionTypeId: 6,
  deductionTypeTitle: "TypeTitle1",
  deductionExchangeTypeId: 3,
  deductionExchangeTypeTitle: "Exchange1",
  wageTitle: "wageTitle7"
}, {
  id: 12,
  deductionTypeId: 6,
  deductionTypeTitle: "TypeTitle1",
  deductionExchangeTypeId: 3,
  deductionExchangeTypeTitle: "Exchange1",
  wageTitle: "wageTitle8"
}];

ReactDOM.render(
  <div>
    <h3>DEMO - Sort And Group Data</h3>
    <Thingy data={rawData} />
  </div>,
  document.getElementById("rd")
);
<div id="rd"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

Explanation

Method: groupAndSort

  • First, deep-clone the array (so the original remains as-is)
  • This is done using [...arr.map(x => ({...x})] --> multiple ... spread operators
  • Now, add 3 props l1, l2, l3 to each array element
  • Use .sort checking to see if each of the levels match (ie, Type, Exchange, Wage Titles)
  • The nested ternary operators ?: may be replaced by if ... else if ... construct (if preferred)
  • Finally, .map one last time to populate the new props added (ie, l1, l2, l3)
  • The implicit return within the method groupAndSort returns the resulting array

JSX:

  • First, use .map to iterate the result
  • Render l1, l2, l3 in individual lines
  • Next, for reference use JSON.stringify to render the actual array returned from the method groupAndSort
  • Related