1

Need some advice on how to create a JSON object by looping through an array without duplicating some of the keys

I am given an array that I need to split up into an object but without duplicating one of the keys

For example:

var myArray = [
    "name/ServiceV1/20190201/1/index.html",
    "name/ServiceV2/20190201/1/index.html",
    "name/ServiceV2/20190201/2/index.html",
    "name/ServiceV2/20190201/3/index.html",
    "name/ServiceV2/20190203/3/index.html",
    "name/ServiceV3/20190213/1/index.html"
];

Returns

[
    {
        "name": {
            "ServiceV1": {
                "20190201": {
                    "1": "index.html"
                }
            },
            "ServiceV2": {
                "20190201": {
                    "1": "index.html",
                    "2": "index.html",
                    "3": "index.html"
                },
                "20190203": {
                    "1": "index.html"
                },
            },
            "ServiceV3": {
                "20190213": {
                    "1": "index.html"
                },
            }
        }
    }
]

How could I get this to work? The code below is what I have already

var jsonify = function() {
  var myArray = [
    "name/ServiceV1/20190201/1/index.html",
    "name/ServiceV2/20190201/1/index.html",
    "name/ServiceV2/20190201/2/index.html",
    "name/ServiceV2/20190201/3/index.html",
    "name/ServiceV2/20190203/3/index.html",
    "name/ServiceV3/20190213/1/index.html"
  ];
  let end = [];

  // Loop through all the myArray items
  for (let i = 0; i < myArray.length; i++) {
    var itemparts = myArray[i].split("/");

    var newObject = {};
    var value = itemparts.pop();
    while (itemparts.length) {
      var obj = {};
      if (newObject.hasOwnProperty(itemparts.pop())) {
        return;
      } else {
        newObject[itemparts.pop()] = value;
      }
      obj[itemparts.pop()] = value;
      value = obj;
    }
    end.push(value);
  }

  // return the results
  return end;
};

But that returns this:

[
  {
    "name": {
      "ServiceV1": {
        "20190201": {
          "1": "index.html"
        }
      }
    }
  },
  {
    "name": {
      "ServiceV2": {
        "20190201": {
          "8": "index.html"
        }
      }
    }
  },
  {
    "name": {
      "ServiceV2": {
        "20190201": {
          "9": "index.html"
        }
      }
    }
  },
  {
    "name": {
      "ServiceV2": {
        "20190201": {
          "17": "index.html"
        }
      }
    }
  }
]

So I'm kinda lost on where to go next

2

1 Answer 1

2

Stephen, you're creating new objects and pushing them onto the end of an array, which will always result in a list that gets longer and longer.

Your initial wording already hints at what's wrong: "how to create a JSON object".

Instead of creating new objects to add to a list, work with only one object that you modify/update. Keep in mind objects are references in JavaScript.

I use recursion in this example because it's a beautiful fit.

// WARNING: This code assumes a very specific text structure.
// It's for a specific use case, not a generic solution. Details in comments below.
const result = {};  // References are immutable in JS' const, not values.
const texts = [
    'a/b/c/file1.html',
    'b/c/d/file2.html',
    'a/b/e/file3.html'
];

function gluePartsToObject(obj, parts) {
    // End of the line.
    if (parts.length === 1) return parts.shift();

    // We've still got some ways to go.
    const part = parts.shift();
    if (obj.hasOwnProperty(part)) {
        // Re-use object reference.
        obj[part] = gluePartsToObject(obj[part], parts);
    } else {
        // Don't have an object yet to reference, create one.
        obj[part] = gluePartsToObject({}, parts);
    }
    
    return obj;
}

// ES2015 "of". Can be replaced with a regular loop for compatibility.
for (text of texts) {
    let parts = text.split('/');
    gluePartsToObject(result, parts);
}

console.log(result);

Sign up to request clarification or add additional context in comments.

1 Comment

That's awesome! It works just how I need it too thank you and thank you for the commented code :)

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.