Основная идея не сложна: группируйте по первой записи, затем по второй записи и т. Д., Пока не получите что-то вроде этого:
(A,XX,22,33)
(A,XX,777,888)
-------------------------
(A,YY,33,11)
(A,YY,13,23)
=============
(B,XX,12,0)
-------------------------
(B,YY,44,98)
, а затем работайте задом наперед, чтобы построить деревья.
Тем не менее, существует рекурсивный компонент, который несколько затрудняет рассуждение об этой проблеме или показывает ее шаг за шагом, поэтому на самом деле проще написать псевдокод.
Я предполагаю, что каждая строка в вашем CSV представлена как кортеж. Каждый кортеж имеет «записи» и «значения», используя те же термины, которые вы используете в своем вопросе. «Записи» - это вещи, которые необходимо поместить в иерархическую структуру. «Ценностями» будут листья дерева. Я буду использовать цитаты, когда я использую эти термины с этими конкретными значениями.
Я также предполагаю, что все «записи» предшествуют всем «значениям».
Без лишних слов, код:
// builds tree and returns a list of root nodes
// list_of_tuples: a list of tuples read from your csv
// curr_position: used to keep track of recursive calls
// number_of_records: assuming each csv row has n records and then m values, number_of_records equals n
function build_tree(list_of_tuples, curr_position, number_of_records) {
// check if we have already reached the "values" (which shouldn't get converted into trees)
if (curr_position == number_of_records) {
return list of nodes, each containing a "value" (i.e. everything from position number_of_records on)
}
grouped = group tuples in list_of_tuples that have the same value in position curr_position, and store these groups indexed by such common value
unique_values = get unique values in curr_position
list_of_nodes = empty list
// create the nodes and (recursively) their children
for each val in unique_values {
the_node = create tree node containing val
the_children = build_tree(grouped[val], curr_position+1, number_of_records)
the_node.set_children(the_children)
list_of_nodes.append(the_node)
}
return list_of_nodes
}
// in your example, this returns a node with "A" and a node with "B"
// third parameter is 2 because you have 2 "records"
build_tree(list_parsed_from_csv, 0, 2)
Теперь вам нужно подумать о конкретных структурах данных, которые следует использовать, но, надеюсь, это не должно быть слишком сложно, если вы понимаете алгоритм (как вы упоминаете, я думаю, что решение о структуре данных на раннем этапе, возможно, мешало ваши мысли).