0

Below is the object I have

var data = {
  sku: ['1', '2', '3', '4'],
  color: [],
  season: ['winter', 'summer'],
}

Below is the output I'm expecting

data = [
  { sku: '1', season: 'winter'},
  { sku: '2', season: 'summer'},
  { sku: '3'},
  { sku: '4'},
]

Below is the working script but not easy to read. Please suggest if you have any better suggestion.

var data = {
  sku: ['1', '2', '3', '4'],
  color: [],
  season: ['winter', 'summer'],
}

var arr = Object.entries(data)
  .filter(item => item[1] && item[1].length) // remove empty values
  .sort((x, y) => y[1].length - x[1].length) // bring lengthy value to first

var final = arr[0][1].map((a, index) =>
  arr.reduce((b, acc) => ({
    ...b,
    ...(acc[1][index] && { [acc[0]]: acc[1][index] }),
  }), {})
);

console.log(final);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
w3debugger
  • 2,097
  • 19
  • 23
  • 1
    “Expecting” of which code? Familiarize yourself with [how to access and process nested objects, arrays or JSON](/q/11922383/4642212) and how to [create objects](//developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Object_initializer) and use the available static and instance methods of [`Object`](//developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object#Static_methods) and [`Array`](//developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array#Static_methods). – Sebastian Simon Sep 06 '21 at 21:57
  • What did you try? Where got you stuck? – Peter Seliger Sep 06 '21 at 21:58
  • @PeterSeliger Just asking the question gave me -2, I can't imagine about sharing the code. ‍♂️ – w3debugger Sep 06 '21 at 22:04
  • 3
    @w3debugger ... As I know SO any somehow reasonable attempt would have spared you the downvotes. But just dropping the Q without showing an effort did the opposite. There are people that are really strict about that. But they are mostly willing too, taking the vote back after the OP does edit the Q accordingly. – Peter Seliger Sep 06 '21 at 22:09
  • 4
    Indeed, right now this question is "gimme the code". Showing your effort would've prevented that. Still, it is interesting that you think posting your attempt would've resulted in more downvotes :/ –  Sep 06 '21 at 22:16
  • 1
    @w3debugger ... out of curiosity, the example code you did provide in the end, was this your 1st approach? And if so, why did you not post it? And since it also does its job, where was your actual problem? The only suggestion i have ... write human readable code (readable after some month too), for yourself and others. – Peter Seliger Sep 06 '21 at 23:35
  • 1
    @PeterSeliger I knew how to get the result but as you can see it is not readable. That's why I asked if anyone can suggest less and clear code. I wrote the code after posting it. AFAIK this platform is not only expert guys posting perfect answers and experts posting answers. I was really disappointed by seeing negative impression but in the end learnt the mindset majority has... BTW Thanks :) – w3debugger Sep 06 '21 at 23:52

2 Answers2

1

function createListOfObjectsFromValuesConfig(config) {
  const [

    // the entry list with the maximum length `value` list.
    primaryEntryList,
    // the list of all remaining entry lists.
    ...listOfSecondaryEntries

  ] = Object
    // get an array of entries, each entry an array itself,
    // a tuple of an entry's key and value.
    .entries(config)
    // sort the array of entry arrays descending by
    // comparing the `value` array's `length`properties.
    .sort((a, b) => b[1].length - a[1].length);

  const [

    primaryKey,
    primaryValueList,

  ] = primaryEntryList;

  return primaryValueList
    .map((primaryValue, primaryIndex) => {

      return listOfSecondaryEntries
        .reduce((dataItem, [secondaryKey, secondaryValueList]) => {

          if (secondaryValueList.hasOwnProperty(primaryIndex)) {

            // if possible aggregate the item's
            // initially provided base data.
            Object.assign(dataItem, {

              [secondaryKey]: secondaryValueList[primaryIndex]
            });
          }
          return dataItem;

        }, { [primaryKey]: primaryValue }); // create the item's base.
    });
}

var data = {
  sku: ['1', '2', '3', '4'],
  color: [],
  season: ['winter', 'summer'],
};

console.log(
  'createListOfObjectsFromValuesConfig(data) ...',
  createListOfObjectsFromValuesConfig(data)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
1

Using vanilla JS you can transpose (zip) the arrays using Array.from() with Array.map(). Then map the array of arrays, combine to pairs with the original keys, and filter out pairs with value that is undefined. Afterwards you can convert the array of pairs to an object using Object.fromEntries():

const zip = (...arr) =>
  Array.from({ length: Math.max(...arr.map(a => a.length)) }, (_, i) => 
    arr.map(a => a[i])
  )

const createObject = obj => {
  const keys = Object.keys(obj)

  return arr => Object.fromEntries(
    keys.map((key, i) => [key, arr[i]])
      .filter(([, val]) => val !== undefined)
  )
}

const fn = obj => zip(...Object.values(obj)).map(createObject(obj))

const data = {
  sku: ['1', '2', '3', '4'],
  color: [],
  season: ['winter', 'summer'],
}

const result = fn(data)

console.log(result)

With lodash Zip the arrays to an array with sub-arrays that each contains all the values of an object. Then map the array of arrays, and use _.zipObject() to combine the original keys, with a sub-array of values to an object, and then _.omit() the keys with undefined values.

const { omitBy, zipObject, isUndefined, zip } = _

const createObject = obj => {
  const keys = Object.keys(obj)

  return arr => omitBy(zipObject(keys, arr), isUndefined)
}

const fn = obj => zip(...Object.values(obj)).map(createObject(obj))

const data = {
  sku: ['1', '2', '3', '4'],
  color: [],
  season: ['winter', 'summer'],
}

const result = fn(data)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209