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

2 Answers 2

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; }

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

2 Comments

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'}, ], }
this makes the code easier, because you do not need a dynamic key anymore for the finding and new object. please see edit.
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.

1 Comment

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

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.