Создайте строковые пути из вложенного объекта в Javascript

1

Я пытаюсь превратить вложенный объект, представляющий мою файловую систему, в массив строк, которые представляют пути к файлам для каждой папки и файла.

Входные данные:

let obj = {
  'app': {
    'body': {
      'abs': {
        'muscles.txt': 1
      },
      'foot.js': 1,
      'hand.txt': 1,
      'leg.txt': 1
    },
    'cat.txt': 1,
    'dog.js': 1,
    'writing': {
      'pen.txt': 1,
      'phone.txt': 1
    }
  }
};

Выход:

  [
  '/app', 
  '/app/body',
  '/app/body/abs/',
  '/app/body/abs/muscles.txt',
  '/app/body/foot.js',
  '/app/body/hand.txt',
  ...
]

Что я до сих пор (он не работает):

function filePaths(obj, oldKey = '', store = []) {
  for (let key in obj) {
    if (typeof obj[key] === 'object') {
      store.push('/' + key);
      filePaths(obj[key], key, store);
    } else {
      store.push('/' + oldKey + '/' + key);
    }
  }
  return store;
}

filePaths(obj);
  • 0
    Ваш вывод имеет пути, которые иногда имеют косую черту ( /app/body/abs/ ), а иногда нет ( /app , /app/body ). Вы хотите получить результат с этим слешем или без него, или есть другой критерий, по которому его нужно включить или нет?
  • 0
    Да, извините, это ошибка с моей стороны. Я не хотел косой черты. Спасибо за ваш ответ.
Теги:
object
file
recursion
nested

3 ответа

1
Лучший ответ

Вот рабочая версия:

let obj = {
  'app': {
    'body': {
      'abs': {
        'muscles.txt': 1
      },
      'foot.js': 1,
      'hand.txt': 1,
      'leg.txt': 1
    },
    'cat.txt': 1,
    'dog.js': 1,
    'writing': {
      'pen.txt': 1,
      'phone.txt': 1
    }
  }
};

function filePaths(obj, prefix = '', store = []) {
  for (let key in obj) {
    const curPath = '${prefix}/${key}';
    if (typeof obj[key] === 'object') {
      store.push(curPath);      
      filePaths(obj[key], curPath, store);
    } else {
      store.push(curPath);      
    }
  }
  return store;
}

console.log(filePaths(obj));

Поэтому я сохранил большую часть вашего кода, но изменил тот факт, что, сохраняя "старый" ключ, я сохраняю текущий путь и служит префиксом для всех файлов и в качестве префикса для всех каталогов, которые будут получать текущий ключ.

  • 0
    Спасибо, Сильвестр, я знал, что я был близко, но моя логика была немного не в порядке.
0

Здесь рекурсивное решение, которое использует метод Object.keys с оператором распространения, concat и map:

let obj = {
  'app': {
    'body': {
      'abs': {
        'muscles.txt': 1
      },
      'foot.js': 1,
      'hand.txt': 1,
      'leg.txt': 1
    },
    'cat.txt': 1,
    'dog.js': 1,
    'writing': {
      'pen.txt': 1,
      'phone.txt': 1
    }
  }
};

function filePaths(obj, prefix = "", store = []) {
  if (typeof obj !== "object") return [prefix];
  return (prefix && [prefix] || []).concat(...Object.keys(obj).map(k => filePaths(obj[k], prefix + "/" + k, store)))
}

console.log(filePaths(obj))
0

Здесь решение с рекурсией:

let obj = {
  'app': {
    'body': {
      'abs': {
        'muscles.txt': 1
      },
      'foot.js': 1,
      'hand.txt': 1,
      'leg.txt': 1
    },
    'cat.txt': 1,
    'dog.js': 1,
    'writing': {
      'pen.txt': 1,
      'phone.txt': 1
    }
  }
};

const pathify = (o, res=[], path=[]) => {
  for (const prop in o) {
    const s = path.join("/");
    res.push('/${s ? '${s}/${prop}' : prop}');

    if (o[prop] !== 1) {
      pathify(o[prop], res, path.concat(prop));
    }
  }

  return res;
};

console.log(pathify(obj));

объяснение

Перебирайте все свойства объекта и создайте для него путь и добавьте его в массив результатов. Если ключ свойства для чего-то другого, кроме 1, это нетерминальный узел и вызывается рекурсивно для добавления путей для его дочерних элементов.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню