2

I have a tabular mode array object as shown below upto n level. it can be any parent children's records

var records = [
  { country: "USA", state: "FLORIDA", city: "city1" },
  { country: "USA", state: "FLORIDA", city: "city2" },
  { country: "USA", state: "FLORIDA", city:"city3" },
  { country: "USA", state: "ALASKA" },
  { country: "USA", state: "ALBAMA" },
]

var columns = ["country","state","city"]  // upto n column

I need to group in below format for nth level as there can be n level of relations, group records in below format

{
  sequencer: 1, value: 'USA', loop: [
    { sequencer: 1, value: 'FLORIDA', loop: [
      { sequencer: 1, value: 'city1' },
      { sequencer: 2, value: 'city2' },
      { sequencer: 3, value: 'city3' },
    ], },
    { sequencer: 2, value: 'ALASKA' },
    { sequencer: 3, value: 'ALBAMA' },
  ],
}

Can someone write an recursive function to group for n level of column object. Thanks

rajesh
  • 41
  • 4

2 Answers2

1

You could group the data by avoiding unwanted loop properties.

const
    data = [{ country: "USA", state: "FLORIDA", city: "city1" }, { country: "USA", state: "FLORIDA", city: "city2" }, { country: "USA", state: "FLORIDA", city: "city3" }, { country: "USA", state: "ALASKA" }, { country: "USA", state: "ALBAMA" }],
    keys = ['country', 'state', 'city'],
    result = data.reduce((loop, o) => {
        keys
            .map(k => o[k])
            .filter(Boolean)
            .reduce((r, value) => {
                let temp = (r.loop ??= []).find(q => q.value === value);
                if (!temp) r.loop.push(temp = { sequence: r.loop.length + 1, value });
                return temp;
            }, { loop });
        return loop;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Thanks for your answer. Can you please let me know how can I update output column key as value (static key) like below { sequencer: 1, value: 'USA', loop: [ {sequencer: 1, value: 'FLORIDA', loop: [ {sequencer: 1, value: 'city1'}, {sequencer: 2, value: 'city2'}, {sequencer: 3, value: 'city3'}, ],}, {sequencer: 2, value: 'ALASKA'}, {sequencer: 3, value: 'ALBAMA'}, ], } – rajesh Oct 05 '20 at 04:59
  • this makes the code easier, because you do not need a dynamic key anymore for the finding and new object. please see edit. – Nina Scholz Oct 05 '20 at 07:22
0

I answered a similar question recently. You could write your transform using flatMap and recursion -

const transform = ([ name, ...more ], { value, loop = [{}] }, r = {}) =>
  name === undefined
    ? [ r ]
    : loop.flatMap(t => transform(more, t, { [name]: value, ...r }))

const records =
  {sequencer:1,value:'USA',loop:[{sequencer:1,value:'FLORIDA',loop:[{sequencer:1,value:'city1'},{sequencer:2,value:'city2'},{sequencer:3,value:'city3'}]},{sequencer:2,value:'ALASKA'},{sequencer:3,value:'ALBAMA'}]}

const columns =
  ['country', 'state', 'city']

const result =
  transform(["country", "state", "city"], records)
  
console.log(JSON.stringify(result, null, 2))

A function statement equivalent of the => expression above -

function transform
  ( [ name, ...more ]
  , { value, loop = [{}] }
  , r = {}
  )
  { if (name === undefined)
      return [ r ]
    else 
      return loop.flatMap
        ( t =>
            transform
              ( more
              , t
              , { [name]: value, ...r }
              )
        )
  }

Read the original Q&A for more insight on this technique.

Mulan
  • 129,518
  • 31
  • 228
  • 259
  • Thanks I can see it, here I am looking vice versa for same. I need to Group the records unto n level. Can you write vice versa function for same. Thank You – rajesh Oct 05 '20 at 05:28