2

I have a 2-dimensional array that looks like this:

var myArray = [
    ['Name', 'Age', 'Profession'],
    ['John', 34, 'Teacher'],
    ['Jane', 45, 'Artist']
];

I want to transform this array to an object that looks like this:

var myObject =
{
    "Name":
    {
        "Name": "Name",
        "Age": "Age",
        "Profession": "Profession"
    }
    "John":
    {
        "Name": "John",
        "Age": 34,
        "Profession": "Teacher"
    }
    "Jane":
    {
        "Name": "Jane",
        "Age": 45,
        "Profession": "Artist"
    }
};

In another thread I came across Array.prototype.reduce() and I was able to do the following:

var myObject = myArray.reduce(function(result, currentItem) {
  result[currentItem[0]] = currentItem;
  return result;
}, {})

Logger.log(myObject);
// {John=[John, 34.0, Teacher], Jane=[Jane, 45.0, Artist], Name=[Name, Age, Profession]}

However, I don't know how to apply reduce() to get a nested object or if I need a different approach here.

Andreas

Edit:

  • I am looking for an dynamical solution, that is: I don't know beforehand how many elements my array contains or what their values are.
  • I'd prefer a solution that is faster and more elegant than iterating through all elements (if possible).
3
  • Why is the first array index part of the object? Basically all solutions will require you to iterate if it is dynamic. Commented Jan 25, 2016 at 14:41
  • @epascarello: Not sure, if I got your question right: the usage of the names (John, Jane) both as keys and as values is just an easy example. In reality, I will create an unique key out of several values (e.g. name, date of birth and email) and use it as key in my object. Commented Jan 25, 2016 at 15:10
  • Looks like ['Name', 'Age', 'Profession'] is heading for a table, just looked strange you would have an entry for it. Commented Jan 25, 2016 at 15:12

3 Answers 3

2

A solution with reduce and an object and some nested properties.

var myArray = [['Name', 'Age', 'Profession'], ['John', 34, 'Teacher'], ['Jane', 45, 'Artist']],
    result = myArray.reduce(function (r, a) {

        // get the first element ('Name', 'John', 'Jane') of myArray and take it as a key
        // for the object. generate a new object if there is no object available
        // read here: r.Name = r.Name || {}
        r[a[0]] = r[a[0]] || {};

        // iterate over ['Name', 'Age', 'Profession']
        myArray[0].forEach(function (b, i) {

            // assign the according value to the according property of the object
            // read here: r.Name.Name = 'Name'
            // next       r.Name.Age = 'Age'
            r[a[0]][b] = a[i];
        });
        return r;
    }, {});

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

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

1 Comment

This works fine, thank you. But I'm still trying to figure out what it does. Can you add a few words about what is the idea behind the code?
1
myArray.reduce(
function ( r, a )
{
    var row = a.reduce(
        function ( rr, cc, i )
        {
            rr[ myArray[ 0 ][ i ] ] = cc;
            return rr;
        }, {} );

    r[ a[ 0 ] ] = row;
    return r;
}, {} );

The idea is that do the same reduce at each row.

var myArray = [
  ['Name', 'Age', 'Profession'],
  ['John', 34, 'Teacher'],
  ['Jane', 45, 'Artist']
];

var result = myArray.reduce(
  function(r, a) {
    var row = a.reduce(
      function(rr, cc, i) {
        rr[myArray[0][i]] = cc;
        return rr;
      }, {});

    r[a[0]] = row;
    return r;
  }, {});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Comments

0

I think that the easiest way to do this could be using map function

var myArray = [
    ['Name', 'Age', 'Profession'],
    ['John', 34, 'Teacher'],
    ['Jane', 45, 'Artist']
];

var myObjects = myArray.map(function(el) { 
    return { 
        'Name': el[0],
        'Age': el[1],
        'Profession': el[2]
    } 
});

The other way is to just use on for statement

for(int i=1;myArray.length;i++)
{
    var el = myArray[i];
    myObjects2[el[0]] = { 
        'Name': el[0],
        'Age': el[1],
        'Profession': el[2]
    }
}

5 Comments

indeed. Pay attention that array.prototype.map is not available on IE8 and earlier versions (source).
you generate an array, not an object with properties for every item.
Yes I know, but this part is simply enough that I don't want to obfuscate this example. But you can do just myObject2[el[0]] = { ... }
I see, but in my case, I don't know of how many elements my array consists or what they are calle. Sorry, I should have mentioned this in my question.
So @Nina Scholz answer would be better for you

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.