4

I am trying to achieve something which seemed very basic but is getting me mad over the last days.

I have a simple array : ["a","b","c","d","e"] and I want to turn it into a nested JSON like this:

{"a":{"b":{"c":{"d":{"e":""}}}}}

Looping over it, I ran in problems like "how do you save the last key to set it afterwards without erasing it" and so on.

Does anyone has an idea?

3
  • 1
    Why are you doing this? Just for fun? Commented Sep 25, 2014 at 13:51
  • 1
    How will {"a":{"b":{"c":{"d":{"e":""}}}}} help you? Commented Sep 25, 2014 at 13:51
  • I have to build a jade block from a JSON which I have to build from an array ;) Commented Sep 25, 2014 at 13:52

3 Answers 3

4

You might have had problems because you were looping in the wrong direction. Try to build the object from inside-out:

array.reduceRight(function(v, key) {
    var o = {};
    o[key] = v;
    return o;
}, "")

or, with a loop:

var val = "";
for (var i=array.length; i--; )
    var o = {};
    o[array[i]] = val;
    val = o;
}
return val;
Sign up to request clarification or add additional context in comments.

1 Comment

Just what I needed! Never heard of that reduceRight method, very useful, thanks a lot! :)
1

Here's one way to do it, recursively:

function convertToNestedObject(arr) {
    var result = {};

    if (arr.length === 1) {
        result[arr[0]] = '';
    } else {
        result[arr[0]] = convertToNestedObject(arr.slice(1, arr.length));
    }

    return result;
}

You could pass the start index in to the function instead of using slice and creating copies of the array:

function convertToNestedObject(arr, startIndex) {
    var result = {};


    if (arr.length - startIndex === 1) {
        result[arr[startIndex]] = '';
    } else {
        result[arr[startIndex]] = convertToNestedObject(arr, startIndex + 1);
    }

    return result;
}

Example: http://jsfiddle.net/jwcxfaeb/1/

6 Comments

You should make the base case for arr.length == 0
@Bergi: Not sure about that, if arr.length is 0, then accessing the element at arr[0] will return undefined. Unless you meant changing the base case entirely
Yes, I mean changing the base case entirely so that there is no similarity to the recursive case at all - simplifying the whole function.
@Bergi: Okay, I think you're saying make the base case if (arr.length === 0) { return ''; } else { // recursive case }. Is that correct? If so, I don't see how it simplifies things that much. In any case, an iterative approach is much better for this problem anyway.
Yes, exactly. It removes a bit of code duplication, and - more relevant - makes the function work with an empty array.
|
0

Put current element as key and empty object ({}) as value. Continue with newly inserted empty object.

function toNested(arr){
    var nested = {};
    var temp = nested;

    for(var i=0; i<arr.length; i++){
        temp[arr[i]] = {};
        temp = temp[arr[i]];
    }

    return nested;
}

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.