0

Let's say I have a variable named data

const data = [
        {loanname: "Mr X", acnumber:  "020000000000001", outstanding: "54000"},
        {loanname: "Mrs Y", acnumber: "020000000000087", outstanding: "87000"},
        {loanname: "Mr Z", acnumber:  "020000000000103", outstanding: "15000"},
        {totalaccount: "3", outstanding: "156000"},
        {loanname: "David", acnumber: "020000000000091", outstanding: "11000"},
        {loanname: "James", acnumber: "020000000001291", outstanding: "4000"},
        {totalaccount: "2", outstanding: "15000"},

    ]

It's an array. I would like to extract data items depending on how many times there are totalaccount. For example, before the first totalaccount, there are three accounts. I would like to extract them.

Also, before the last totalaccount, there are two accounts if we can skip the first totalaccount. I would like to extract information for those two accounts.

To be more precise, how can I convert the array into the following?:

let firstOne = {loanname: "Mr X", acnumber:  "020000000000001", outstanding: "54000"},
    {loanname: "Mrs Y", acnumber: "020000000000087", outstanding: "87000"},
    {loanname: "Mr Z", acnumber:  "020000000000103", outstanding: "15000"},

let secondOne ={loanname: "David", acnumber: "020000000000091", outstanding: "11000"},
    {loanname: "James", acnumber: "020000000001291", outstanding: "4000"}, 
Rashel
  • 95
  • 6

2 Answers2

3

You can easily achieve this result using reduce.

First of all, check if there is totalaccount property exists or not. If yes then create a new array in the acc using the push method of Array.prototype If totalaccount property doesn't exists then just push the object in the last array of acc. You need to track the last array element index with current

const data = [
  { loanname: "Mr X", acnumber: "020000000000001", outstanding: "54000" },
  { loanname: "Mrs Y", acnumber: "020000000000087", outstanding: "87000" },
  { loanname: "Mr Z", acnumber: "020000000000103", outstanding: "15000" },
  { totalaccount: "3", outstanding: "156000" },
  { loanname: "David", acnumber: "020000000000091", outstanding: "11000" },
  { loanname: "James", acnumber: "020000000001291", outstanding: "4000" },
  { totalaccount: "2", outstanding: "15000" },
];

let current = 0;
const result = data.reduce((acc, curr) => {
    const { totalaccount } = curr;
    if (totalaccount) {
      acc.push([]);
      ++current;
    } else {
      acc[current].push(curr);
    }
    return acc;
  },
  [[]]
);

const [first, second] = result;
console.log(first);
console.log(second);
console.log(result);

You can also achieve the same result without tracking the current as

const data = [
  { loanname: "Mr X", acnumber: "020000000000001", outstanding: "54000" },
  { loanname: "Mrs Y", acnumber: "020000000000087", outstanding: "87000" },
  { loanname: "Mr Z", acnumber: "020000000000103", outstanding: "15000" },
  { totalaccount: "3", outstanding: "156000" },
  { loanname: "David", acnumber: "020000000000091", outstanding: "11000" },
  { loanname: "James", acnumber: "020000000001291", outstanding: "4000" },
  { totalaccount: "2", outstanding: "15000" },
];

const result = data.reduce(
  (acc, curr) => {
    const { totalaccount } = curr;
    if (totalaccount) {
      acc.push([]);
    } else {
      acc[acc.length - 1].push(curr);
    }
    return acc;
  },
  [[]]
);

console.log(result);

If you want to accumulate into one object and want to create property dynamically

const data = [
  { loanname: "Mr X", acnumber: "020000000000001", outstanding: "54000" },
  { loanname: "Mrs Y", acnumber: "020000000000087", outstanding: "87000" },
  { loanname: "Mr Z", acnumber: "020000000000103", outstanding: "15000" },
  { totalaccount: "3", outstanding: "156000" },
  { loanname: "David", acnumber: "020000000000091", outstanding: "11000" },
  { loanname: "James", acnumber: "020000000001291", outstanding: "4000" },
  { totalaccount: "2", outstanding: "15000" },
];

const result = data.reduce(
  (acc, curr) => {
    const { totalaccount } = curr;
    if (totalaccount) {
      acc.push([]);
    } else {
      acc[acc.length - 1].push(curr);
    }
    return acc;
  },
  [[]]
);

const resultObj = {};
result.forEach((d, i) => {
  if (d.length) {
    resultObj[`collection${i + 1}`] = [...d];
  }
});
console.log(resultObj);
DecPK
  • 24,537
  • 6
  • 26
  • 42
  • It returns all the account numbers. It doesn't split the numbers depending on "totalaccount". In my question I asked if I could convert the array into variables named "firstOne" and "secondOne". Because there are "totalaccount" two times, I would like the array to split into two parts. If there are "totalaccount" 3 times, I would like the array to split into three parts and so on. How can I do that? – Rashel May 26 '21 at 02:49
  • It will do that for you just check the result array... – DecPK May 26 '21 at 02:50
  • @Rashel—you can't conditionally create arbitrary variables within a loop like *firstOne*, *secondOne*, etc. You can either create an array or an object that has properties with the required names and assign the results to them, see [*Dynamically Creating Variables for Loops*](https://stackoverflow.com/questions/6645067/javascript-dynamically-creating-variables-for-loops?r=SearchResults&s=1|144.1670). – RobG May 26 '21 at 02:58
  • Since `result` will return an array of array so you can get the data with array indexes. – DecPK May 26 '21 at 02:59
  • @decpk Your code works for me. I needed the result to split into multiple parts because they are different type of loans and I will need them separate for future calculation. – Rashel May 26 '21 at 03:04
  • @Rashel Edited the code and accumulated the result into one object with dynamic property. Check it out... – DecPK May 26 '21 at 03:05
  • @decpk Thanks for your help. Highly appreciated. – Rashel May 26 '21 at 03:08
0

try this logic (not tested completely, just an idea)

const myArray = [];
for (let i = 0; i < data.length; i++) {
  if (!data[i].totalaccount) continue;
    myArray.push([]);
    for (let x = i - data[i].totalaccount; x <= i - 1; x++) {
      myArray[myArray.length-1].push(data[x]);
    }
}
console.log(myArray);
Eric Cheng
  • 477
  • 1
  • 9
  • 24