4

I'm new to Javascript and I'm having trouble parsing an INI formatted file into nested objects.

The file I have is formatted like this:

ford.car.focus.transmission=standard
ford.car.focus.engine=four-cylinder
ford.car.focus.fuel=gas

ford.car.taurus.transmission=automatic
ford.car.taurus.engine=V-8
ford.car.taurus.fuel=diesel

purchased=Ford Taurus

I would like to have the structure look like this:

{ ford:
  { car:
    { focus:
      {
        transmission: 'standard',
        engine: 'four-cylinder',
        fuel: 'gas'
      }
    }
    { taurus:
      {
        transmission: 'automatic',
        engine: 'V-8',
        fuel: 'diesel'
      }
    }
  }
  purchased: 'Ford Taurus'
}

I'm storing the file in lines in an array, splitting on '\n'. I'm trying to write a method that would be called in a loop, passing my global object like this:

var hash = {};
var array = fileData.toString().split("\n");
for (i in array) {
  var tmp = array[i].split("=");
  createNestedObjects(tmp[0], tmp[1], hash);
}

This should let me access the values in the hash object like:

hash.ford.car.focus.fuel
# 'gas'

hash.purchase
# 'Ford Taurus'

I've tried something like what was suggested here: Javascript: how to dynamically create nested objects using object names given by an array, but it only seems to set the last item in the nest.

{ fuel: 'diesel',
  purchased: 'Ford Taurus' }

My unsuccessful attempt looks like this:

createNestedObjects(path, value, obj) {
  var keys = path.split('.');
  keys.reduce(function(o, k) {
    if (k == keys[keys.length-1]) {
      return o[k] = value;
    } else {
      return o[k] = {};
    }
  }, obj);
}

However, it will only return the last value for the nested values:

{ ford: { car: { taurus: { fuel: 'diesel' } } },
  purchased: 'Ford Taurus' }
1
  • 2
    createNestedObjects doesn't check whether the key already exists in the object, so it replaces it if it already exists. Commented Apr 9, 2016 at 0:25

1 Answer 1

3

The function needs to check whether an intermediate key already exists before assigning to it.

function createNestedObjects(path, value, obj) {
    const keys = path.split('.');
    keys.reduce(function (o, k) {
        if (k == keys[keys.length - 1]) {
            return o[k] = value;
        }
        return o[k] ??= {};
    }, obj);
}
Sign up to request clarification or add additional context in comments.

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.