Один подход к выравниванию рекурсивной структуры класса с рекурсивной функцией.
Вот класс, который мы хотели бы сгладить:
public class Nested {
public let n : Int
public let sub : [Nested]?
public init(_ n:Int, _ sub:[Nested]?) {
self.n = n
self.sub = sub
}
}
Вот функция, которая демонстрирует как это можно сделать:
func test() {
let h = [
Nested(1, [Nested(2, nil), Nested(3, nil)])
, Nested(4, nil)
, Nested(5, [Nested(6, nil), Nested(7, [Nested(8, nil), Nested(9, nil)])])
]
func recursiveFlat(next:Nested) -> [Nested] {
var res = [Nested]()
res.append(next)
if let subArray = next.sub {
res.appendContentsOf(subArray.flatMap({ (item) -> [Nested] in
recursiveFlat(item)
}))
}
return res
}
for item in h.flatMap(recursiveFlat) {
print(item.n)
}
}
Сердцем этого подхода является локальная функция recursiveFlat
. Он добавляет содержимое вложенного объекта к результату, а затем условно вызывает себя для каждого элемента, чтобы добавить его содержимое.
, Что Вам нравится использовать в качестве работы вокруг? Контейнерные объекты или Макросы? Вы чувствуете стоящий того?
канонический путь состоит в том, чтобы использовать метафункцию как таким образом:
template <typename T>
struct my_string_map {
typedef std::map<std::string, T> type;
};
// Invoke:
my_string_map<int>::type my_str_int_map;
Это также используется в STL (allocator::rebind<U>
) и во многих библиотеках включая Повышение. Мы используем его экстенсивно в биоинформатическая библиотека .
Это чрезмерно увеличено в размере, но это - лучшие альтернативные 99% времени. Используя макросы здесь не стоит многих оборотных сторон.
(РЕДАКТИРОВАНИЕ: я исправил код для отражения соглашений Повышения/STL, как указано Daniel в его комментарии.)
Шаблон
struct my_string_map: public std :: map { };
Вы не должны наследовать от классов, которые не имеют виртуального деструктора. Это связано с деструкторами в полученных классах, не вызываемых, когда они должны быть, и вы можете в конечном итоге с нераспределенной памятью.
Это говорит, что вы можете *****, вероятно, ***** сойти с ним в приведенном выше экземпляре, потому что вы не добавляете больше данных в ваш производный тип. Обратите внимание, что это не одобрение. Я все еще советую вам не Сделай это. Тот факт, что вы могут , это не значит, что вы должны .
Редактировать: Да, это ответ на пост Shachris23. Я, наверное, пропустил что-то, потому что он появился над его / ее сообщением, а не ниже.