Сократите каждый узел дерева в список кончиков дерева - PullRequest
0 голосов
/ 25 ноября 2018

Вот исполняемый код: https://gist.github.com/the1mills/61d53438a3dce1da32640d3e05a611a6

(я не мог понять, как загрузить асинхронную библиотеку, используя JSBin или RequireBin онлайн, возможно, кто-то знает, как это сделать).

У меня есть такая древовидная структура:

const animals = {
  canines: {
    dogs: {
      poodle: {
        val: true
      }
    },
    fox:{
      val: true
    },
    wolf: {
      northwestern:{
        val: true
      },
      arctic: {
        val: true
      }
    },
    raccoon:{
      val: true
    }
  },
  porpoises: {
    vaquita:{
      val: true
    },
    harbor: {
      val: true
    }
  },

};

Для каждого узла в дереве я хочу получить описание каждой ветви от этого узла, сократив ключи ветви до одного ключа, чтобы я получил:

  // canines node: 
[{"Dogs.Poodle": true}, {"Fox":true}, {"Wolf.Northwestern":true}, {"Wolf.Arctic":true}, {"Raccoon" : true}]

   // porpoisies node: 
[{"Vaquita": true}, {"Harbor":true}]

   // and at the animals node:
 [{"Canines.Dogs.Poodle": true}, {"Canines.Fox":true}, {"Canines.Wolf.Northwestern":true}, {"Canines.Wolf.Arctic":true}, {"Canines.Raccoon" : true}, {"Porpoises.Vaquita": true}, {"Porpoises.Harbor":true}]

У меня есть этот код, но я не могу понять, что с ним не так.Мне нужно сохранить его асинхронным, потому что я буду делать так, ввод-вывод, но мы можем смоделировать это с помощью process.nextTick для целей вопроса.

const uppercaseFirstChar = s => {
  return s.slice(0,1).toUpperCase() + s.slice(1).toLowerCase();
};


const loop = (v, list, cb) => {

  const results = [];

  async.eachLimit(Object.keys(v), 3, (k, cb) => {

    const sub = v[k];

    if (sub && typeof sub === 'object') {

      for (let l of list) {
        l.push({
          key: k
        });
      }

      return loop(sub, list.concat([results]), err => {

        const path = results.reduce((a, b) => {
          return {
            val: a.val,
            key: uppercaseFirstChar(a.key) + '.' + uppercaseFirstChar(b.key)
          }
        });

        console.log({path});

        cb(err);
      });
    }

    for (let l of list) {
      l.push({
        val: sub,
        key: k
      });
    }

    process.nextTick(cb);


  }, cb);

};

const list = [];

loop(animals, list, (err, val) => {
  console.log(err, val);
});

В моем коде для каждого узла яглядя на дорожки деревьев, и я получаю некоторые дикие результаты, я не могу понять, почему.

1 Ответ

0 голосов
/ 25 ноября 2018

Когда код сжимается / сворачивается сам, вы обычно знаете, что находитесь на правильном пути:

const loop = (v, cb) => {

  const results = [];

  async.eachLimit(Object.keys(v), 3, (k, cb) => {

    const sub = v[k];

    if (sub && typeof sub === 'object') {

      return loop(sub, (err, values) => {

        for(let v of values){
          results.push(k + v);
        }

        cb(err);
      });
    }


    results.push(k);
    process.nextTick(cb);


  }, err => {
     cb(err, results);
  });

};


loop(animals, (err, val) => {
  console.log(err, val);
});

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

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