Question

This is problem-solving q; nothing's gone wrong, I'm just stumped about how to advance. Basically I want my users to be able to

  1. Point to an arbitrary key of an object with arbitrary depth via a string representation of the "path";
  2. Confirm that each step of the "path" exists; and
  3. Implement CRUD-like functionality

I can verify that each key is valid, but I'm just stumped on how to then utilize said path without ultimately using an eval() statement, but of course I needn't explain why I'm not going to let a call to eval() get anywhere near arbitrary user input. Here's as far as I can get:

const SEP = "/" //in reality this is set by the server,
MyObjInterface = function() {
    this.params = {};
    this.response = {};

    // suppose some initialization business, then on to the question... ( >.>)

    this.updateOb= function(path, value ) {
        path = path.replace('\\' + DS,"$DIRECTORY_SEPARATOR").split(DS);

        for (var i = 0; i < path.length; i++) {
            path[i].replace("$DIRECTORY_SEPARATOR",DS);
        }

        if (typeof(path) != "object" || path.length < 3) { // 3 = minimum depth to reach a valid field in any rset scheme
            throw "Could not create rset representation: path either incorrectly formatted or incomplete."
        }

        var invalidPath = false;
        var searchContext = path[0] === "params" ? this.params : this.response;
        for (var i = 1; i < path.length - 1; i++) {
            if (invalidPath) { throw "No key found in rset at provided path: [" + path[i] + "]."; }

            if (i === path.length - 1) {
                searchContext[path[1]] = value;
                return true;
            }
            if (path[i] in searchContext) {
                searchContext = searchContext[path[i]];
            } else {
                invalidPath = true;
            }

        }
    }
};
Was it helpful?

Solution

You break the path up in to components, then you recursively walk the tree.

My JS is weak, so I'll pseudo code.

path = "go.down.three";
listOfElements = breakUpPath(path); // Now listOfElement = ["go", "down", "three"];
myObj = setObjectValue(myObj, listOfElement, "I'm a value");

function setObjectValue(obj, listOfElements, value) {
    var firstPart = pop(listOfElements); // get and remove top of listOfElements stack
    if (length(listOfElements) == 0) { // last element of the path, set the value
        obj[firstPart] = value;
        return obj;
    } else {
        // check if a property exists at all
        var firstValue = obj[firstPart];
        if (firstValue == null) {
            firstValue = new Object();
            obj[firstPart] = firstValue;
        }
        obj[firstPart] = setObjectValue(firstValue, listOfElement, value);
    }
}

So, my as I said, my JS is weak (really weak, I can't really even spell JavaScript). Needless to say, this is untested.

But something like that is what you're looking for. Just work your way down the elements of the path.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top