2

I have a function has just one variable(foo) and that is:

{
  'a': {
    'b': {
      'c': 12,
      'd': 'Hello World'
    },
    'e': [1,2,3]
  }
}

and now I need to convert that to this:

{
  'a/b/c': 12,
  'a/b/d': 'Hello World',
  'a/e': [1,2,3]
}

Including all property types like functions, true or false, arrays, numbers, strings and so on.

NOTE: Please do not write the code snippet that achieves this and don't give it to me. Just give me a few tips on what I should use and what the algorithm is. Then, if I am not able to write the code, I will tell you to give me the code.

Thanks

Sotiris Kiritsis
  • 3,178
  • 3
  • 23
  • 31
Amir
  • 31
  • 6
  • [This question might help](http://stackoverflow.com/questions/722668/traverse-all-the-nodes-of-a-json-object-tree-with-javascript). Simply keep track of the traversals until a child is hit, then store the value with the property `root/node1/node2/...`. – Spencer Wieczorek Jul 11 '16 at 04:57
  • 1
    and what have you tried before coming here ? – Mritunjay Jul 11 '16 at 04:57
  • nothing special. just Google and Stackoverflow. @Mritunjay – Amir Jul 11 '16 at 04:59
  • I couldn't use jQuery. but Thanks @SpencerWieczorek – Amir Jul 11 '16 at 05:02
  • 1
    @Mahdi The top answer doesn't use jQuery. – Spencer Wieczorek Jul 11 '16 at 05:03
  • Aha, Thanks. But as i said I hope to write code myself not someone else. but there's no problem. @SpencerWieczorek – Amir Jul 11 '16 at 05:05
  • @Mahdi That code is just to show how to traverse through all properties in a object, it's helpful, but won't solve the problem. – Spencer Wieczorek Jul 11 '16 at 05:07
  • I know you said no code but I have tested my code sample below to now work. I think it is about as simple and efficient as you can get it. – Adrian Brand Jul 11 '16 at 05:35
  • Thank you Adrian, it returns arrays separately. e.g: g/a/e/1 = 1 g/a/e/2 = 3 and so on. 1- How can i return them like g/a/e: [1,2,3]? 2- another thing that I can't is that I like to have quotes around g/a/e/1. like 'g/a/e/1' 3- And finally another problem is equal sign. I need colon instead of that. Thanks @AdrianBrand – Amir Jul 11 '16 at 06:24

3 Answers3

2

I would take a recursive approach where a single call iterates over the properties and put the keys into an array and if the value is an object, i would call the function again with the actual value and the array with the visited keys.

function flatKeys(object) {

    function iter(part, keys) {
        Object.keys(part).forEach(function (k) {
            if (part[k] !== null && !Array.isArray(part[k]) && typeof part[k] === 'object') {
                return iter(part[k], keys.concat(k));
            }
            flat[keys.concat(k).join('/')] = part[k];
        });
    }

    var flat = {};
    iter(object, []);
    return flat;
}

var object = { a: { b: { c: 12, d: 'Hello World' }, e: [1, 2, 3] } };

console.log(flatKeys(object));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Thank you so much Nina. You had written a code before this code that is not correct. I didn't see this code but now I see this and it's completely right. @nina – Amir Jul 11 '16 at 10:25
  • the first edition was just how i would make it. later i wrote it. – Nina Scholz Jul 11 '16 at 10:48
1

Untested code but should get you going

function flatten(obj) {
  var retVal = {};

  traverse(obj, '');

  return retVal;

  function traverse(obj, path) {
    for (prop in obj) {
      if (obj[prop] && typeof(obj[prop]) === 'object')
        traverse(obj[prop], path ? path + '/' + prop : prop);
      else
        retVal[path ? path + '/' + prop : prop] = obj[prop];
    }
  };
}

var obj = {
  a: {
    b: {
      c: 12,
      d: 'Hello World'
    },
    e: [1,2,3]
  }
};
var result = flatten(obj);
result = JSON.stringify(result, null, 2);

$("#result").text(result);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<pre id="result"></pre>
Toxantron
  • 2,218
  • 12
  • 23
Adrian Brand
  • 20,384
  • 4
  • 39
  • 60
0

looping through each key of object should work too.

check below code so u can modify it to fulfill your needs

var obj = {
  'a': {
    'b': {
      'c': 12,
      'd': 'Hello World'
    },
    'e': [1,2,3]
  }
};
var newObj = {};
var temp = ''

var objectLooper = function(obj, removeParent, parent) {


var objKeys = Object.keys(obj);

for (var i = 0; i< objKeys.length; i++) {
console.log(typeof obj[objKeys[i]])
if (typeof obj[objKeys[i]] === 'object' && typeof obj[objKeys[i]].length === 'undefined'){
//loop again

temp += temp.length > 0 ? '/' + objKeys[i] :  objKeys[i];

objectLooper(obj[objKeys[i]], true, objKeys[i])
}else {
//temp += temp.length > 0 ?  :  objKeys[i];
newObj[temp +'/' + objKeys[i]] = obj[objKeys[i]]
}
}
if(removeParent === true) {
temp = temp.split('/' +parent).join()
}
}

objectLooper(obj)
newObj;
Arif
  • 1,617
  • 9
  • 18