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

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.