admin管理员组

文章数量:1297014

I've methods on SO for flattening an array javascript, i.e. converting [1,[2,3]] into [1,2,3]. But I'm looking for a concise method of flattening a dictionary while preserving the keys. Specifically, I want a dictionary that looks like this:

{'key1':1,'key2':{'key3':2,'key4':3,'key5':{'key6':4}}}

To be converted into:

{'key1':1, 'key2.key3':2,'key2.key4':3,'key2.key5.key6':4}

The exact output format (dictionary, list of pairs, etc) isn't important, as long as it clearly associates the string of nested keys with a value. For my purposes, it's also OK to assume that none of the keys contain a . character, so that it can be used to denote the next key.

I've methods on SO for flattening an array javascript, i.e. converting [1,[2,3]] into [1,2,3]. But I'm looking for a concise method of flattening a dictionary while preserving the keys. Specifically, I want a dictionary that looks like this:

{'key1':1,'key2':{'key3':2,'key4':3,'key5':{'key6':4}}}

To be converted into:

{'key1':1, 'key2.key3':2,'key2.key4':3,'key2.key5.key6':4}

The exact output format (dictionary, list of pairs, etc) isn't important, as long as it clearly associates the string of nested keys with a value. For my purposes, it's also OK to assume that none of the keys contain a . character, so that it can be used to denote the next key.

Share asked Feb 26, 2014 at 16:20 J-bobJ-bob 9,12613 gold badges57 silver badges89 bronze badges 1
  • underscorejs has some useful functions for manipulating data structures. – js1568 Commented Feb 26, 2014 at 16:24
Add a ment  | 

4 Answers 4

Reset to default 5
var keys = {'key1':1,'key2':{'key3':2,'key4':3,'key5':{'key6':4}}};
var result = {};

function serialize(keys, parentKey){
    for(var key in keys){
        if(parseInt(keys[key], 10)){
            result[parentKey+key] = keys[key];
        }else{
            serialize(keys[key], parentKey+key+".");
        }
    }
}
serialize(keys, "");
console.log(result);

Hope this is what you want:

{ key1: 1, 'key2.key3': 2, 'key2.key4': 3, 'key2.key5.key6': 4 }

Here is another approach to the problem.

var myDict = {'key1':1,'key2':{'key3':2,'key4':3,'key5':{'key6':4}}};

function flattenDict(dictToFlatten) {
    function flatten(dict, parent) {
        var keys = [];
        var values = [];

        for(var key in dict) {
            if(typeof dict[key] === 'object') {
                var result = flatten(dict[key], parent ? parent + '_' + key : key);
                keys = keys.concat(result.keys);
                values = values.concat(result.values);
            }
            else {
                keys.push(parent ? parent + '_' + key : key);
                values.push(dict[key]);
            }
        }

        return {
            keys : keys,
            values : values
        }
    }

    var result = flatten(dictToFlatten);
    var flatDict = {};

    for(var i = 0, end = result.keys.length; i < end; i++) {
        flatDict[result.keys[i]] = result.values[i];
    }

    return flatDict;
}

flattenDict(myDict);

This code does not use global variable for storing the result.

var dict = {'key1':1,'key2':{'key3':2,'key4':3,'key5':{'key6':4}}};

function flatten(obj, suffix, ans) {

  for (var x in obj) {
      var key;
      if (suffix != '')
        key = suffix + '.' + x;
      else
        key = x;
    if (typeof obj[x] === 'object') {
      flatten(obj[x], key, ans);
    } else {
      ans[key] = obj[x];
    }
  }
}
var x = {};
flatten(dict, "", x)
console.log(x)

This is a modified version of @SPS where I take in account a scenario like: {"a": {"b": {"": "Test"} } };

// {"a": {"b": {"": "Test"} } };

function flatten(dict) {
    let res = {}
    helper(dict, "", res);
    return res;
  }
  
function helper(obj, suffix, ans) {
    for (let k in obj) {
        let key;
        if (suffix !== '' && k !== '') {
            key = `${suffix}.${k}`;
        } else if (suffix !== '' && k === '') {
            key = suffix;
        } else {
            key = k;
        }
        
        if (typeof obj[k] === 'object') {
            helper(obj[k], key, ans);
        } else {
            ans[key] = obj[k];
        }
    }
}

本文标签: Flattening a Javascript dictionarypreserving the nested keysStack Overflow