2016-04-08 3 views
0

Мне дано множество различных шаблонов символов, см. Ниже data, и я пытаюсь вложить данные в иерархическую форму JSON для вставки в визуализацию солнечных лучей. Каждый шаблон состоит из n символов, хотя те, которые указаны ниже, составляют 8 символов. Чтобы обсудить желаемый результат:Char Sequence к иерархическому JSON - d3.sunburst

  1. На уровне 0 найдите количество уникальных символов. Ответ: ['w', 'm'].
  2. Возьмите первый ключ «w» и найдите все уникальные символы, которые находятся на уровне 1, затем перейдите на уровень 2 и так далее, пока не нанесете конец рисунку, в котором мы вычисляем размер этого уникального рисунка в конце.
  3. Повторите # 2 для второго ключа 'm'
  4. Вставьте результат в children property of root.

Я смог построить код для двухуровневого корпуса и впоследствии мог бы глубже вложить много гнезд, но он был бы очень жестко запрограммирован и очень трудно понять. Кто-нибудь знает, как я мог бы сделать это рекурсивно или с другим шаблоном, который бы разрешил его?

Желаемая Выход Пример:

var root = {"name":"evt_seq","children":[{"name":"w","children":[{"name":"w","size":8},{"name":"k","size":1}]},{"name":"m","children":[{"name":"w","size":1}]}]} 

Два уровня вложенности (Глядя на п уровень вложенности)

"use strict"; 
var data = [{"match": ["w", "w", "l", "w", "w", "w", "t", "w"]}, {"match": ["w", "k", "w", "A", "w", "w", "w", "w"]}, 
{"match": ["w", "w", "w", "w", "w", "w", "w", "w"]}, {"match": ["w", "w", "w", "w", "w", "w", "w", "w"]}, 
{"match": ["w", "w", "w", "w", "w", "w", "w", "w"]}, {"match": ["m", "w", "v", "v", "t", "m", "l", "m"]}, 
{"match": ["w", "w", "w", "l", "w", "w", "l", "l"]}, {"match": ["w", "w", "z", "w", "w", "m", "l", "w"]}, 
{"match": ["w", "w", "w", "w", "w", "w", "w", "w"]}, {"match": ["w", "w", "m", "w", "l", "w", "w", "w"]} 
]; 

var root = { 
    "name": "evt_seq", children: [] 
}; 
// Get initial pattern 
var groupedXs = _.groupBy(data, function (d) { 
    return d.match[0]; 
}); 
_.forEach(_.keys(groupedXs), function (d) { 
    let _x = groupedXs[d]; 
    let _groupedXs = _.groupBy(_x, function (f) { 
     return f.match[1]; 
    }); 
    let _children = _.map(_.keys(_groupedXs), function (f) { 
     return {'name': f, 'size': _groupedXs[f].length} 
    }); 
    root.children.push({"name": d, children: _children}); 
}); 
console.log(JSON.stringify(root)); 

ответ

2

Это, безусловно, решена лучше всего с рекурсивным алгоритмом. Поскольку синтаксис кажется менее важным, я просто дам краткий psudeo-код:

function subTree(inputs) { 
    var children = [] 
    var leadingLetters = //map first letter from each array, remove duplicates 
    for leadingLetter in leadingLetters { 
     var matchingInputs = //filter inputs that match the first letter 
     var reducedInputs = //copy of matchingInputs, but the first (matching) element is removed from each array 
     children.push(subTree(reducedInputs)) 
    } 
    return children 
} 
var root = subTree(data); 

Я не обрабатывать пустые дети массива как пустые, так как я не совсем уверен, что ожидать, когда вы дойдете до конца из строк. В любом случае, это должно помочь вам. (PS Надеюсь, это было не для домашнего задания! = X)

+0

Спасибо за помощь @Acey! – hotshotiguana

0

@Acey - отличное руководство! Ниже приведена полная работа. Еще раз спасибо, и это за личный проект, а не домашнюю работу :)

function subTree(inputs) { 
    var children = []; 
    var leadingLetters = _.uniq(_.map(inputs, function (d) { 
     return d.match[0]; 
    })); //map first letter from each array, remove duplicates 
    _.forEach(leadingLetters, function (leadingLetter) { 
      var matchingInputs = _.filter(inputs, function (d) { 
       return d.match[0] == leadingLetter; 
      }); //filter inputs that match the first letter 
      var reducedInputs = _.map(matchingInputs, function (d) { 
       return {"match": d.match.slice(1, d.match.length)}; 
      }); //copy of matchingInputs, but the first (matching) element is removed from each array 
      if (!reducedInputs[0].match.length) { 
       children.push({name: leadingLetter, size: reducedInputs.length}); 
      } 
      else { 
       children.push({"name": leadingLetter, children: subTree(reducedInputs)}); 
      } 
     } 
    ); 
    return children 
} 

var root = subTree(data);