Рекурсивно читать каталог и создавать объект в NodeJS - PullRequest
0 голосов
/ 13 февраля 2019

Я изо всех сил пытался автоматизировать и убрать, как я использую генерацию и загрузку спрайтов в моей игре HTML5, используя сервер NodeJS socket.io для отправки объекта, содержащего данные, необходимые для генерации спрайтов.

Что я хочу сделать для достижения этой цели, так это прочитать каталог /img и все его подкаталоги (/assets1, /assets2, /assets3 и т. Д.) И создать объект на основе данных и их структуры.,Проблема, с которой я столкнулся, заключалась в том, что я не мог найти хороший способ справиться с подкаталогами, скажем, /assets3.Вот как мои активы настроены в качестве примера:

Directory structure

А вот пример объекта, которого я хочу достичь, но не смог без использования бесконечного if / else s, который, честно говоря, не кажется мне привлекательным, и должен быть лучший способ использования библиотеки.

var outputWeWant = {
  assets1: {
    img1: '/img/assets1/img1.png',
    img2: '/img/assets1/img2.png',
  },
  assets2: {
    img1: '/img/assets2/img1.png',
    img2: '/img/assets2/img2.png',
  },
  assets3: {
    img1: '/img/assets3/img1.png',
    img2: '/img/assets3/img2.png',
    assets4: {
      img1: '/img/assets3/assets4/img1.png'
    }
  }
}

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

  fs.readdirSync('/img/').map(dirName => {
    fs.readdirSync('/img/' + dirName).map(fileName => {
      if (fs.statSync('/img/' + dirName + '/' + fileName).isDirectory()) {
        // Read the new directory and add the files to our object
      } else {
        // It's not a directory, just add it to our object
      }
    });
  });

1 Ответ

0 голосов
/ 13 февраля 2019

Этот тип потенциально бесконечной операции требует рекурсивной функции .Я собираюсь предположить, что эта функция должна быть написана для Node, и я оставлю детали файловой системы для OP. Этот фрагмент должен рассматриваться как псевдокод.

function parseDirectory(directory) {
  return directory.getItems().reduce((out, item) => {
    switch (item.type) {
      case 'file':
        out[item.name] = item.path;
        break;

      case 'directory':
        out[item.name] = parseDirectory(item.path);
        break;
    }

    return out;
  }, {});
}

С добавленным кодом fs в OP вот (теоретически) рабочая функция:

function parseDirectory(directory) {
  return fs.readdirSync(directory).reduce((out, item) => {
    const itemPath = `${directory}/${item}`;

    if (fs.statSync(itemPath).isDirectory()) {
      out[item] = parseDirectory(itemPath);
    } else {
      out[item] = itemPath;
    }

    return out;
  }, {});
}

Если синтаксис reduce() слишком сложный для вашего вкуса, попробуйте следующее:

function parseDirectory(directory) {
  let out = {};

  fs.readdirSync(directory).forEach(item => {
    const itemPath = `${directory}/${item}`;

    if (fs.statSync(itemPath).isDirectory()) {
      out[item] = parseDirectory(itemPath);
    } else {
      out[item] = itemPath;
    }
  });

  return out;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...