admin管理员组

文章数量:1319953

I have an object like this:

data:
{
    connection:
    {
        type: 0,
        connected: false
    },
    acceleration:
    {
        x: 0,
        y: 0,
        z: 0,
        watchId: 0,
        hasError: false
    }        
},

Converting it to flat array like this:

"connected": false
"hasError": false
"type": 0
"watchId": 0
"x": 0
"y": 0
"z": 0

is an easy task (recurrence is your friend!).

But is there any way in Javascript to get it with so called full parents, i.e. something like this:

"connection.connected": false
"acceleration.hasError": false
"connection.type": 0
"acceleration.watchId": 0
"acceleration.x": 0
"acceleration.y": 0
"acceleration.z": 0

Or am I expecting to much?

I have an object like this:

data:
{
    connection:
    {
        type: 0,
        connected: false
    },
    acceleration:
    {
        x: 0,
        y: 0,
        z: 0,
        watchId: 0,
        hasError: false
    }        
},

Converting it to flat array like this:

"connected": false
"hasError": false
"type": 0
"watchId": 0
"x": 0
"y": 0
"z": 0

is an easy task (recurrence is your friend!).

But is there any way in Javascript to get it with so called full parents, i.e. something like this:

"connection.connected": false
"acceleration.hasError": false
"connection.type": 0
"acceleration.watchId": 0
"acceleration.x": 0
"acceleration.y": 0
"acceleration.z": 0

Or am I expecting to much?

Share Improve this question asked Aug 7, 2013 at 16:28 trejdertrejder 17.5k27 gold badges131 silver badges225 bronze badges 4
  • 6 There is no reason that such code could not be written. – Pointy Commented Aug 7, 2013 at 16:30
  • Sure, as you said recurrence[sic] is your friend. Just pass forward the current property name appended to the previous as a string. – user2437417 Commented Aug 7, 2013 at 16:32
  • This should be EASIER than what you've already done, since you won't have to iterate over the internal objects' properties. You're going from an object full of objects to an array full of the same objects. – user2625787 Commented Aug 7, 2013 at 16:33
  • possible duplicate of pressing object hierarchies in JavaScript – Bergi Commented Aug 7, 2013 at 17:05
Add a ment  | 

4 Answers 4

Reset to default 3

Another variant:

function flatten(o) {
  var prefix = arguments[1] || "", out = arguments[2] || {}, name;
  for (name in o) {
    if (o.hasOwnProperty(name)) {
      typeof o[name] === "object" ? flatten(o[name], prefix + name + '.', out) : 
                                    out[prefix + name] = o[name];
    }
  }
  return out;
}

invoke like flatten(data);

There's always a way, but note that both of these are objects, neither is an array. (associative arrays in Javascript are just objects ).

function objectFlatten( o , n ) {
        var p   =   {}
            ,   n = n? n : ''
            ,   merge = function(a,b){ for( k in b) a[k] = b[k]; return a;}
            ;

        for( i in o ) {
            if( o.hasOwnProperty( i ) ) {
                if( Object.prototype.toString.call( o[i] ) == '[object Object]' || Object.prototype.toString.call( o[i] ) == '[object Array]')
                    p = merge( p , objectFlatten( o[i] , n? n + '.' + i : i ) );
                else
                    p[i] = o[i];

                }
            }

        return p;
   }

For posterity - check out flat or a similar utility I wrote for Forms JS, Flatten.

My five cents.

For cases when you want flatten objects but not properties

In other words.

You have something like this:

var obj = {
  one_a: {
    second_a: {
      aaa: 'aaa',
      bbb: 'bbb'
    },
    second_b: {
      qqq: 'qqq',
      third_a: {
        www: 'www',
        eee: 'eee',
        fourth_a: {
          'rrr': 'rrr',
          fifth: {
            ttt: 'ttt'
          }
        },
        fourth_b: {
          yyy: 'yyy',
        }
      },
      third_b: {
        'uuu': 'uuu'
      }
    }
  },
  one_b: {
    iii: 'iii'
  }
}

And want to make nested object flat, but don't want to flat properties:

{ 'one_a second_a ': { aaa: 'aaa', bbb: 'bbb' },
  'one_a second_b ': { qqq: 'qqq' },
  'one_a second_b third_a ': { www: 'www', eee: 'eee' },
  'one_a second_b third_a fourth_a ': { rrr: 'rrr' },
  'one_a second_b third_a fourth_a fifth ': { ttt: 'ttt' },
  'one_a second_b third_a fourth_b ': { yyy: 'yyy' },
  'one_a second_b third_b ': { uuu: 'uuu' },
  'one_b ': { iii: 'iii' } }

Code:

function flatten (obj, includePrototype, into, prefix) {
  into = into || {};
  prefix = prefix || "";

  for (var k in obj) {
    if (includePrototype || obj.hasOwnProperty(k)) {
      var prop = obj[k];
      if (prop && typeof prop === "object" && !(prop instanceof Date || prop instanceof RegExp)) {
        flatten(prop, includePrototype, into, prefix + k + " ");
      }
      else {
        if (into[prefix] && typeof into[prefix] === 'object') {
          into[prefix][k] = prop
        } else {
          into[prefix] = {}
          into[prefix][k] = prop
        }
      }
    }
  }

  return into;
}

Based on closure's answer

本文标签: javascriptCovert JS object into flat array with parent namesStack Overflow