6

I need to update the object name based on the array of the string value and the last string value should be an array.

I use array.forEach loop but I don't know how to find the object inside an object if it exists and the myArray contain around 10,000 strings.

const myArray = [
  '/unit/unit/225/unit-225.pdf',
  '/nit/nit-dep/4.11/nit-4.11.pdf',
  '/nit/nit-dep/4.12/nit-4.12.pdf',
  '/org/viti/viti-engine/5.1/viti-engine-5.1.pdf',
  '/org/viti/viti-spring/5.1/viti-spring-5.1.pdf'
];
var parentObject = {}
myArray.forEach(res => {
  res = res.slice(1, res.length);
  var array = res.split("/");
  array.forEach((e, i) => {
    ........ // here I am confused 

  });
})

final output should be

parentObject = {
  'unit': {
    'unit': {
      '225': {
        'unit-225.pdf': []
      }
    }
  },
  'nit': {
    'nit-dep': {
      '4.11': {
        'nit-4.11.pdf': []
      },
      '4.12': {
        'nit-4.12.pdf': []
      }
    }
  },
  'org': {
    'viti': {
      'viti-engine': {
        '5.1': {
          'viti-engine-5.1.pdf': []
        }
      },
      'viti-spring': {
        '5.2': {
          'viti-engine-5.2.pdf': []
        }
      }
    }
  }
}

3 Answers 3

3

Once you've split by slashes, use reduce to iterate to the nested object, creating each nested property first if necessary, then assign an array to the filename property:

const myArray = [
  '/unit/unit/225/unit-225.pdf',
  '/nit/nit-dep/4.11/nit-4.11.pdf',
  '/nit/nit-dep/4.12/nit-4.12.pdf',
  '/org/viti/viti-engine/5.1/viti-engine-5.1.pdf',
  '/org/viti/viti-spring/5.1/viti-spring-5.1.pdf'
];
var parentObject = {}
myArray.forEach((str) => {
  const props = str.slice(1).split('/');
  const filename = props.pop();
  const lastObj = props.reduce((a, prop) => {
    if (!a[prop]) {
      a[prop] = {};
    }
    return a[prop];
  }, parentObject);
  lastObj[filename] = [];
});
console.log(parentObject);

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

Comments

2

You could reduce the array an reduce the path as well. At the end assign the array.

const
    array = ['/unit/unit/225/unit-225.pdf', '/nit/nit-dep/4.11/nit-4.11.pdf', '/nit/nit-dep/4.12/nit-4.12.pdf', '/org/viti/viti-engine/5.1/viti-engine-5.1.pdf', '/org/viti/viti-spring/5.1/viti-spring-5.1.pdf'],
    result = array.reduce((r, path) => {
        var keys = path.split(/\//).slice(1),
            last = keys.pop();

        keys.reduce((o, k) => o[k] = o[k] || {}, r)[last] = [];
        return r;
    }, {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

A slightly faster approach.

const
    array = ['/unit/unit/225/unit-225.pdf', '/nit/nit-dep/4.11/nit-4.11.pdf', '/nit/nit-dep/4.12/nit-4.12.pdf', '/org/viti/viti-engine/5.1/viti-engine-5.1.pdf', '/org/viti/viti-spring/5.1/viti-spring-5.1.pdf'],
    result = {};

for (let path of array) {
    let keys = path.split(/\//).slice(1),
        last = keys.pop(),
        temp = result;

    for (let key of keys) {
        temp[key] = temp[key] || {};
        temp = temp[key];
    }
    temp[last] = [];
}

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0

You could also take a recursive approach.

Just keep shifting the split-up path until you get the final assignment for each branch.

const myArray = [
  '/unit/unit/225/unit-225.pdf',
  '/nit/nit-dep/4.11/nit-4.11.pdf',
  '/nit/nit-dep/4.12/nit-4.12.pdf',
  '/org/viti/viti-engine/5.1/viti-engine-5.1.pdf',
  '/org/viti/viti-spring/5.1/viti-spring-5.1.pdf'
];

console.log(buildTree(myArray));

function buildTree(list=[]) {
  return list.reduce((node, item) => buildBranches(node, item.split(/\//g).filter(x => x !== '')), {});
}

function buildBranches(node={}, rest=[]) {
  let key = rest.shift();
  node[key] = rest.length < 2 ? { [rest.shift()] : [] } /** or rest.shift() */ : node[key] || {};
  if (rest.length > 1) buildBranches(node[key], rest);
  return node;
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

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.