2

私は、1 つの演習で以下のデータ構造をトラバースし、すべてのファイル (つまり、*.js、*.css) を含む配列を返すように要求するプロジェクトに取り組んでいます。

var fileData = {
  dir : 'app',
  files : [
    'index.html',
    {
      dir : 'js',
      files: [
        'main.js',
        'app.js',
        'misc.js',
        {
          dir : 'vendor',
          files : [
            'jquery.js',
            'underscore.js'
          ]
        }
      ]
    },
    {
      dir : 'css',
      files : [
        'reset.css',
        'main.css'
      ]
    }
  ]
};

listFilesパラメータを指定fileDataして呼び出すと、目的の配列が返されるように、再帰的なソリューションを思いつきました。

function listFiles(data) {
  var retval = [];
  var files;

  (function crawl(filedata) {
    files = filedata.files;

    if (typeof files !== 'undefined') {
      for (var i = 0; i < files.length; i++) {
        if (typeof files[i] === 'string') {
          retval.push(files[i]);
        } else {
          crawl(files[i]);
        }
      }
    }
  })(data);

  return retval;
}

ただし、コードを実行すると、*.js のみが返されます。これは、 directoryappで、私のプログラムは 3 つの要素すべてをトラバースすることになっていますが、2 番目の再帰呼び出しの後、3 番目 (/css) をチェックしません。誰でも理由を説明できますか?どうもありがとう!

4

1 に答える 1

5

files変数を再帰関数に対してローカルにする必要があります。それ以外の場合、再帰すると、呼び出し元で使用されている値が上書きされます。

function listFiles(data) {
  var retval = [];

  (function crawl(filedata) {
    var files = filedata.files;

    if (typeof files !== 'undefined') {
      for (var i = 0; i < files.length; i++) {
        if (typeof files[i] === 'string') {
          retval.push(files[i]);
        } else {
          crawl(files[i]);
        }
      }
    }
  })(data);

  return retval;
}
于 2013-01-08T02:59:07.320 に答える