0

I would like to use lodash to generete object from array of arrays. I use for it lodash.zipObject method and map. But it is not 1:1 what I would like to generate:

Input:

 "rows": [
    [
      "stravi/aa",
      "202001",
      "59",
      "51",
      "2558.98",
      "0.5358894453719162",
      "1.9204668112983725",
      "140",
      "2.3466309084813943"
    ],
    [
      "stravi/ab",
      "202003",
      "3591",
      "349",
      "2246.09",
      "0.41838214",
      "3.57603358",
      "50",
      "4.82115474"
    ],
    [
      "stravi/ac",
      "202007",
      "3354",
      "25",
      "1975.76",
      "0.74220667708",
      "1.12321555541",
      "11",
      "0.9324532454"
    ]
  ]

dictionary: ['source', 'sessions', 'adClicks', 'adCost', 'CPC', 'CTR', 'goalCompletionsAll', 'goalConversionRateAll' ], [action.yearReportData]

output:

{
  source: ['stravi/aa', 'stravi/ab', 'stravi/ac'],
  sessions: ['202001', '202003', '202007']
  ...
}

I would like to use lodash, and I try by:

   lodash.map(rows, arr =>
                lodash.zipObject(['source', 'sessions', 'adClicks', 'adCost', 'CPC', 'CTR', 'goalCompletionsAll', 'goalConversionRateAll'], arr))

But is not correct... I received multiple object. I would like to have one object with all data. Like my example.

3 Answers 3

1

Unzip the rows to transpose the sub-arrays, and then use zip object:

const { flow, unzip, zipObject } = _

const fn = flow(
  unzip,
  arr => zipObject(['source', 'sessions', 'adClicks', 'adCost', 'CPC', 'CTR', 'goalCompletionsAll', 'goalConversionRateAll'], arr)
)

const rows = [["stravi/aa","202001","59","51","2558.98","0.5358894453719162","1.9204668112983725","140","2.3466309084813943"],["stravi/ab","202003","3591","349","2246.09","0.41838214","3.57603358","50","4.82115474"],["stravi/ac","202007","3354","25","1975.76","0.74220667708","1.12321555541","11","0.9324532454"]]

const result = fn(rows)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

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

Comments

1

why use third-party library, if may easy do it like so

let result = rows.reduce((obj, arr) => {
  arr.forEach((item, i) => {
    if (!obj[dictionary[i]]) {
      obj[dictionary[i]] = [];
    }
    obj[dictionary[i]].push(item);
  })
  return obj;
}, {});

Comments

1

You need a reducer instead of map. Map just transform each elements that is why you get multiple elements.

I would use plain JS for this one. It will look like this:

const rows = [
  [
    'stravi/aa',
    '202001',
    '59',
    '51',
    '2558.98',
    '0.5358894453719162',
    '1.9204668112983725',
    '140',
    '2.3466309084813943',
  ],
  [
    'stravi/ab',
    '202003',
    '3591',
    '349',
    '2246.09',
    '0.41838214',
    '3.57603358',
    '50',
    '4.82115474',
  ],
  [
    'stravi/ac',
    '202007',
    '3354',
    '25',
    '1975.76',
    '0.74220667708',
    '1.12321555541',
    '11',
    '0.9324532454',
  ],
];

const keys = [
  'source',
  'sessions',
  'adClicks',
  'adCost',
  'CPC',
  'CTR',
  'goalCompletionsAll',
  'goalConversionRateAll',
  'missingFieldName',
];

const initialAcc = keys.reduce((acc, cur) => {
  acc[cur] = [];
  return acc;
}, {});

const resultAcc = rows.reduce((acc, cur) => {
  cur.forEach((value, index) => acc[keys[index]].push(value));
  return acc;
}, initialAcc);

console.log(resultAcc);

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.