0

Hi I am struggling trying to use array.reduce() to get the grouping correct for the following scenario:

here is my starting array:

    {
              {
                descriptionFunction: "Change",
                processDate: "2019-12-12",
                transactionEffectiveDate: "2019-12-12",
                policyEffectiveDate: "2019-09-09",
                policyExpirationDate: "2020-09-09",
                documentID: "1234"
              },
              {
                descriptionFunction: "Change",
                processDate: "2019-12-06",
                transactionEffectiveDate: "2019-12-07",
                policyEffectiveDate: "2019-09-09",
                policyExpirationDate: "2020-09-09",
                documentID: "1235"
              },
              {
                descriptionFunction: "Change",
                processDate: "2019-11-29",
                transactionEffectiveDate: "2019-11-29",
                policyEffectiveDate: "2018-09-09",
                policyExpirationDate: "2019-09-09",
                documentID: "1236"
              },
              {
                descriptionFunction: "Change",
                processDate: "2019-11-29",
                transactionEffectiveDate: "2019-11-29",
                policyEffectiveDate: "2018-09-09",
                policyExpirationDate: "2019-09-09",
                documentID: "1237"
              }
 }
        

here is what i need to come up with:

  {
    "policyEffectiveDate": "2019-09-09",
    "policyExpirationDate": "2020-09-09",
    "transactions": [
      {
        "transactionEffectiveDate": "2019-12-12",
        "descriptionFunction": "Change",
        "documents": [
          {
            "descriptionSubType": "Policy",
            "documentID": "1234"
          }
        ]
      },
      {
        "transactionEffectiveDate": "2019-12-07",
        "descriptionFunction": "Change",
        "documents": [
          {
            "descriptionSubType": "Policy",
            "documentID": "1235"
          }
        ]
      }
    ]
  },
  {
    "policyEffectiveDate": "2018-09-09",
    "policyExpirationDate": "2019-09-09",
    "transactions": [
      {
        "transactionEffectiveDate": "2018-11-29",
        "descriptionFunction": "Change",
        "documents": [
          {
            "descriptionSubType": "Policy",
            "documentID": "1236"
          },
          {
            "descriptionSubType": "Policy",
            "documentID": "1237"
          }
        ]
      }
    ]
  }

So there are two sets of groups in the output, the first by policyEffectiveDate and policyExpirationDate and underneath that by transactionEffectiveDate. I'm struggling trying to figure out how to implement complex groupings with array.reduce structure.

3
  • Do you have to use reduce? While it may be possible, it's probably a more confusing way to write it. Use ordinary loops or forEach() with side effects on a result variable. Commented Jun 24, 2020 at 20:20
  • 1
    where do you get descriptionSubType from? Commented Jun 24, 2020 at 20:41
  • arrg sorry! descriptionSubType was another value in the original array that i missed here so its descriptionFunction: "Change", "descriptionSubType": "Policy",....etc Commented Jun 24, 2020 at 22:37

4 Answers 4

2

You could specify the wanted nesting by taking an array of key for gouping and other keys for the actual level, as well as the key the the nested array.

This works for an arbitrary count of nesting levels for grouping.

var data = [{ descriptionFunction: "Change", processDate: "2019-12-12", transactionEffectiveDate: "2019-12-12", policyEffectiveDate: "2019-09-09", policyExpirationDate: "2020-09-09", documentID: "1234" }, { descriptionFunction: "Change", processDate: "2019-12-06", transactionEffectiveDate: "2019-12-07", policyEffectiveDate: "2019-09-09", policyExpirationDate: "2020-09-09", documentID: "1235" }, { descriptionFunction: "Change", processDate: "2019-11-29", transactionEffectiveDate: "2019-11-29", policyEffectiveDate: "2018-09-09", policyExpirationDate: "2019-09-09", documentID: "1236" }, { descriptionFunction: "Change", processDate: "2019-11-29", transactionEffectiveDate: "2019-11-29", policyEffectiveDate: "2018-09-09", policyExpirationDate: "2019-09-09", documentID: "1237" }],
    groups = [
        ['policyEffectiveDate', 'policyExpirationDate', 'transactions'],
        ['transactionEffectiveDate', 'descriptionFunction', 'documents'],
        [undefined, 'documentID', undefined]
    ],
    result = data.reduce((r, o) => {
        groups.reduce((p, [group, ...properties]) => {
            function setProperties(target = {}) {
                properties.forEach(k => target[k] = o[k]);
                return target;
            }

            var collection = properties.pop(),
                temp;

            if (!group) {
                p.push(setProperties());
                return [];
            }

            temp = p.find(q => o[group] === q[group]);
            if (!temp) {
                p.push(temp = setProperties({ [group]: o[group] }));
                temp[collection] = [];
            }

            return temp[collection];
        }, r)
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

0

here is something you can use :)

const searchArray = [
  {
    descriptionFunction: "Change",
    processDate: "2019-12-12",
    transactionEffectiveDate: "2019-12-12",
    policyEffectiveDate: "2019-09-09",
    policyExpirationDate: "2020-09-09",
    documentID: "1234",
  },
  {
    descriptionFunction: "Change",
    processDate: "2019-12-06",
    transactionEffectiveDate: "2019-12-07",
    policyEffectiveDate: "2019-09-09",
    policyExpirationDate: "2020-09-09",
    documentID: "1235",
  },
  {
    descriptionFunction: "Change",
    processDate: "2019-11-29",
    transactionEffectiveDate: "2019-11-29",
    policyEffectiveDate: "2018-09-09",
    policyExpirationDate: "2019-09-09",
    documentID: "1236",
  },
  {
    descriptionFunction: "Change",
    processDate: "2019-11-29",
    transactionEffectiveDate: "2019-11-29",
    policyEffectiveDate: "2018-09-09",
    policyExpirationDate: "2019-09-09",
    documentID: "1237",
  },
];

const arr = searchArray.reduce((acc, child) => {
  // You need to check if the `acc` has the child array's policy date's child.
  // So
  let policyDate = acc.find(
    (ch) =>
      ch.policyEffectiveDate === child.policyEffectiveDate &&
      ch.policyExpirationDate === child.policyExpirationDate
  );
  // if you can't find it create one and push it to `acc`
  if (!policyDate) {
    policyDate = {
      policyEffectiveDate: child.policyEffectiveDate,
      policyExpirationDate: child.policyExpirationDate,
      transactions: [],
    };
    acc.push(policyDate);
  }
  // after this we are gonna look policyDate.transactions if there is a
  // data contains `transactionEffectiveDate` and `descriptionFunction`
  let transactionData = policyDate.transactions.find(
    (ch) =>
      ch.transactionEffectiveDate === child.transactionEffectiveDate &&
      ch.descriptionFunction === child.descriptionFunction
  );
  // again we are gonna check if this object is there
  if (!transactionData) {
    // if not create one for us
    transactionData = {
      transactionEffectiveDate: child.transactionEffectiveDate,
      descriptionFunction: child.descriptionFunction,
      documents: [],
    };
    policyDate.transactions.push(transactionData);
  }
  // after here we have the transactionData.documents to push
  transactionData.documents.push({
    // since child.descriptionSubType doesn't exists we can maybe do this?
    // I couldn't see where you find `descriptionSubType`
    descriptionSubType: child.descriptionSubType || "Policy",
    documentID: child.documentID,
  });

  return acc;
}, []);

console.log(arr);

Comments

0

Try using for loop.

  1. Try making a "2-D Array" and key as policyEffective Date.
  2. Push all object with same policyEffective Date in same key and then you can go ahead.

Try to do it. Its easy. You will learn a lot.

Comments

0

Solution for SINGLE document:

        const transactions = [{
            descriptionFunction: "Change",
            processDate: "2019-12-12",
            transactionEffectiveDate: "2019-12-12",
            policyEffectiveDate: "2019-09-09",
            policyExpirationDate: "2020-09-09",
            documentID: "1234"
        }, {
            descriptionFunction: "Change",
            processDate: "2019-12-06",
            transactionEffectiveDate: "2019-12-07",
            policyEffectiveDate: "2019-09-09",
            policyExpirationDate: "2020-09-09",
            documentID: "1235"
        }, {
            descriptionFunction: "Change",
            processDate: "2019-11-29",
            transactionEffectiveDate: "2019-11-29",
            policyEffectiveDate: "2018-09-09",
            policyExpirationDate: "2019-09-09",
            documentID: "1236"
        }, {
            descriptionFunction: "Change",
            processDate: "2019-11-29",
            transactionEffectiveDate: "2019-11-29",
            policyEffectiveDate: "2018-09-09",
            policyExpirationDate: "2019-09-09",
            documentID: "1237"
        }];
        
        const groupedTransactions = transactions.reduce((acc, cur) => {
            const groupKey = cur.policyEffectiveDate + cur.policyExpirationDate;
            acc[groupKey]? acc[groupKey].push(cur): acc[groupKey] = [cur];
            return acc;
        }, {});
        
        const transactionsTree = Object.values(groupedTransactions).reduce((acc, cur) => {
            const treeItem = {
                policyEffectiveDate: cur[0].policyEffectiveDate,
                policyExpirationDate: cur[0].policyExpirationDate
            };
            treeItem.transactions = cur.reduce((acc, cur) => {
                acc.push({
                    transactionEffectiveDate: cur.transactionEffectiveDate,
                    descriptionFunction: cur.descriptionFunction,
                    documents:[{
                        descriptionSubType: "Policy",
                        documentID: cur.documentID
                    }] 
                });
                return acc;
            }, []);
            acc.push(treeItem);
            return acc;
        }, []);
        document.getElementById('inputTransactions').innerHTML = JSON.stringify(transactions, null, 4);
                document.getElementById('groupedTransactions').innerHTML = JSON.stringify(transactionsTree, null, 4);
<table>
  <tr>
    <td style="border: 1px solid #cdcdcd"><pre id="inputTransactions"></pre></td>
    <td style="border: 1px solid #cdcdcd"><pre id="groupedTransactions"></pre></td>
  </tr>
</table>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.