0

I have converted the following CSV file

Col1;Col2
1;b
2;d
2;e
3;e
2;zz

into the following [ ][ ] (associate array)

[
  ["Col1","Col2"],
  ["1","b"],
  ["2","d"],
  ["2","e"],
  ["3","g"],
  ["2","zz"]
]

The other possibility is an array of the CSV lines where columns are mapped into an object using the spread operator, I picked up from many searches :). This approach would handle more columns naturally.

[
{0:"Col1", 1:"Col2"},
{0:"1", 1:"b"},
{0:"2", 1:"d"},
...
{0:"2", 1:"zz"},
]

However, I want to make the JSON "hierarchical" and handle repeating field values, here from the left column "Col1" in order to derive the following JSON

{
"1":["b"],
"2":["d","e","zz"],
"3":["g"]
}

How would you go about doing this?

Of course we could generalize the question for n-columns of data where we could have several columns with repeating values (left to right).

Most of my searches seem to hit on duplicate data removal which is not my case, I would like to factor out the repeating fields as shown. I could visualize an iterative method but I hope someone has a .map() perhaps? compact/elegant approach.

Thank you.

Meryan
  • 1,285
  • 12
  • 25
  • This feels like it's already answered somewhere around here, have you tried looking into the Array `map` and `reduce` methods? They are typically handy for stuff like this. Also, your first JSON should fail as it has duplicate key identifiers. – gqstav May 03 '20 at 14:21
  • The closest I came, in last night searches, was this post using JSONObject.accumulate() but then I realized it's JAVA :( I have hard time figuring out how I can **.map** "factor out" repeating fields into a single entry to an array? https://stackoverflow.com/questions/24416960/convert-json-object-with-duplicate-keys-to-json-array – Meryan May 03 '20 at 22:11
  • OK, I'll add an answer to get you started! :-) – gqstav May 04 '20 at 06:05

1 Answers1

1

Let

const initArray = [
  { 0: 'Col1', 1: 'Col2' },
  { 0: '1', 1: 'b' },
  { 0: '2', 1: 'd' },
  ...{ 0: '2', 1: 'zz' },
];

There's definitely a cleaner way of doing this with reduce, but I'll go through the map way of doing it as a start.

  1. const desiredKeys = initArray.map(element => element["0"]), this will give you an array with each desired key as element, i.e. ["1","2",...,"2"]
  2. desiredKeysNoDuplicates = [...new Set(desiredKeys)] removes duplicates so we would have something like ["1","2"]
  3. desiredKeysNoDuplicates.map(element => initArray.map(originalElement => originalElement["0"] === element ? originalElement["1"]: undefined)) will take the keys and find in the original array which elements have matching keys and return their values from the key 1
gqstav
  • 1,984
  • 1
  • 12
  • 18
  • Ok you selected the array of object `[ {} {} ... ]` to work on. I was not suggesting you had to use `.map`, thanks for showing the 1,2,3 steps it helps. I am learning something new like `...new Set(desiredKeys)` although I admit I would have no clue what it means in a month or so. I am very curious about your `reduce` method, please share as a separate answer. – Meryan May 04 '20 at 10:45