0

How do you convert a multi-dimensional array into an array of objects using .reduce()?

Starting array

[
    [
        ['juice', 'apple'], ['maker', 'motts'], ['price', 12]
    ],
    [
        ['juice', 'orange'], ['maker', 'sunkist'], ['price', 11]
    ]
]

And ending array

[
    {juice: 'apple', maker: 'motts', price: 12},
    {juice: 'orange', maker: 'sunkist', price: 11}
]

This is what I have now. This is really just me shooting in the dark.

var transformData = (array) => {
    var newArray = array.push(function (all, item, index) {
        var newItem = item.reduce(function (all, item, index) {
            all[item[0]] = item[1]
            return all
        }, {})
        return all
    }, [])
    newArray.push(newItem)
    return newArray
}
3
  • 1
    you realise you're pushing functions onto the new array Commented Jul 19, 2017 at 5:53
  • try array.map instead of ` array.push(` Commented Jul 19, 2017 at 5:53
  • The odd thing is you think array.push works like array.reduce :p Commented Jul 19, 2017 at 5:57

6 Answers 6

1

You can try a combination of array.map and array.reduce.

Array.push is suited to add element to an array, but if you want to transform all elements of an array to a certain specification, its always better to use array.map

var data = [
    [
        ['juice', 'apple'], ['maker', 'motts'], ['price', 12]
    ],
    [
        ['juice', 'orange'], ['maker', 'sunkist'], ['price', 11]
    ]
]

var result = data.map(function(list){
  return list.reduce(function(o, kv){
    o[kv[0]] = kv[1];
    return o;
  }, {});
})

console.log(result)

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

1 Comment

This is great. I had something similar to this before, but I was using .reduce() in place of .map().
1

You could use Array#map in combination with Object.assign for the properties with a spread syntax ....

var data = [[['juice', 'apple'], ['maker', 'motts'], ['price', 12]], [['juice', 'orange'], ['maker', 'sunkist'], ['price', 11]]], 
    result = data.map(o => Object.assign(...o.map(p => ({ [p[0]]: p[1] }))));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

2 Comments

Does Object.assign(...o.map( have any advantages over array.reduce?
I knew there was a better way :p by the way ... go all the way with ES2015++ - .map(o => Object.assign(...o.map(([k, v]) => ({ [k]: v })))) (though, it does start looking like "brainf*ck" :p)
1

Here is a solution using reduce and foreach.

var items = [
    [
        ['juice', 'apple'], ['maker', 'motts'], ['price', 12]
    ],
    [
        ['juice', 'orange'], ['maker', 'sunkist'], ['price', 11]
    ]
];


var transformData = items.reduce((newArr, currArr) => {
  var obj = {};
  currArr.forEach((x) => {
    obj[x[0]] = x[1];
  });
  return newArr.concat(obj);
},[]);
console.log(transformData);

A solution using two reduce.

var items = [
    [
        ['juice', 'apple'], ['maker', 'motts'], ['price', 12]
    ],
    [
        ['juice', 'orange'], ['maker', 'sunkist'], ['price', 11]
    ]
];


var transformData = items.reduce((newArr, currArr) => {
  return newArr.concat(currArr.reduce((o, arr) =>{
      o[arr[0]] = arr[1];
      return o;
   }, {}));  
},[]);
console.log(transformData);

2 Comments

You can also change it to reduce instead of forEach const obj = currArr.reduce((a,x) => { a[x[0]] = x[1]; return a },{});
Thanks @GerardBanasig updated the solution using two reduce. :)
0

You're actually close, except you seem to think array.push works like array.reduce - it doesn't

var transformData = array => 
    array.map(subarray => 
        subarray.reduce((result, [key, value]) => {
            result[key] = value;
            return result;
        }, {})
    );

Since you're using some ES2015+ features, I used more ... the destructuring of the inner array [key, value]

I just have to add this "extension" to the best answer so far

const transformData=_=>_.map(_=>Object.assign(..._.map(([$,_])=>({[$]:_}))));

Try reading that in a few months and know what it's doing :p

Comments

0

try this:

var parray=[
[
    ['juice', 'apple'], ['maker', 'motts'], ['price', 12]
],
[
    ['juice', 'orange'], ['maker', 'sunkist'], ['price', 11]
]
];

var newArray=[]
parray.forEach(function(data){
var cak  =  data.reduce(function(a, b) {
a[b[0]]=b[1]
  return a;
}, {})
newArray.push(cak)
})
console.log(newArray)

Comments

0

Here's a succinct expression using map and reduce along with object spread syntax.

const data = [
  [
    ['juice', 'apple'], ['maker', 'motts'], ['price', 12]
  ],
  [
    ['juice', 'orange'], ['maker', 'sunkist'], ['price', 11]
  ]
]

const data2 =
  data.map (pairs =>
    pairs.reduce ((o, [k,v]) =>
      ({ ...o, [k]: v }), {}))

console.log (data2)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.