Как различить пару и вложенный map?
Пытаюсь пройтись рекурсивно по map и не могу понять как определить вложенный map, предполагаю что возможно как-то через касты указателей и последующее сравнение?
#include <iostream>
#include <string>
#include <map>
using namespace std;
bool isDictionary(void* ptr) {};
void flattenDictionaryHelper(string initialKey, map<string, void*> dict, map<string, string>& ans)
{
for (auto& kvpair : dict)
{
auto value = dict[kvpair.first];
if (!isDictionary(value)) // ??
{
if (initialKey == "")
ans.insert_or_assign(kvpair.first, to_string(*(int*)&kvpair.second));
else
ans.insert_or_assign(initialKey + "." + kvpair.first, to_string(*(int*)&kvpair.second));
}
else
{
if (initialKey == "")
flattenDictionaryHelper(kvpair.first, *(map<string, void*>*) & value, ans);
else
flattenDictionaryHelper(initialKey + "." + kvpair.first, *(map<string, void*>*) & value, ans);
}
}
}
map<string, string> flattenDictionary(const map<string, void*>& dict)
{
map<string, string> ans;
flattenDictionaryHelper("",dict,ans);
return ans;
}
Ввод
int main()
{
map<string, void*> insidedict3{
{"" , (void*)1}
};
map<string, void*> insidedict2{
{"d",(void*)3},
{"e",(void*)&insidedict3}
};
map<string, void*> insidedict{
{"a", (void*)2},
{"b", (void*)3 },
{"c", (void*)&insidedict2}};
/*
input: dict = {
"Key1" : "1",
"Key2" : {
"a" : "2",
"b" : "3",
"c" : {
"d" : "3",
"e" : {
"" : "1"
}
}
}
}
*/
map<string, void*> dict{ {"Key1",(void*)1},{"Key2",(void*)&insidedict}};
for (auto& in : flattenDictionary(dict))
std::cout << in.first << " : " << in.second << std::endl;
return 0;
}
Ответы (1 шт):
Автор решения: cpp-userium
→ Ссылка
Переделал с помощью темплейтов и ооп.
Осталось 2 проблемы:
- работает нормально только с одним типом данных(см. вывод)
- плохо читается
#include <iostream>
#include <string>
#include <map>
using namespace std;
template<class T>
struct Dict
{
public:
char* type;
void* ptr;
T* realval;
};
class NestedDict : public Dict<map<string, void*>>
{
public:
NestedDict(map<string, void*>* mapptr) : realval(mapptr) { Dict<map<string, void*>>::type = new char('n');};
void* ptr = (void*)realval;
map<string, void*>* realval{};
};
template<class T>
class Value: public Dict<T> // примитивный тип
{
public:
Value(T* val) { Dict<T>::type = new char('k'); Dict<T>::realval = val; };
void* ptr = (void*)Dict<T>::realval;
};
template<class T>
bool isDictionary(Dict<T>* ptr) {
char t = *ptr->type;
if (t == 'n')
return true;
else
return false;
};
template<class T>
void flattenDictionaryHelper(string initialKey, map<string, void*> dict, map<string, string>& ans)
{
for (auto& kvpair : dict)
{
auto value = dict[kvpair.first];
if (!isDictionary((Dict<T>*)value)) // примитивный тип
{
string insert_string;
Value<T>* val = (Value<T>*)value;
T* right_val = (T*)val->realval;
if (initialKey == "")
{
ans.insert_or_assign(kvpair.first, to_string(*right_val));
}
else
ans.insert_or_assign(initialKey + "." + kvpair.first, to_string(*right_val));
}
else // map
{
if (initialKey == "")
flattenDictionaryHelper<T>(kvpair.first, *(((NestedDict*)value)->realval), ans);
else
flattenDictionaryHelper<T>(initialKey + "." + kvpair.first, *(((NestedDict*)value)->realval), ans);
}
}
}
map<string, string> flattenDictionary(const map<string, void*>& dict)
{
map<string, string> ans;
flattenDictionaryHelper<int>("",dict,ans);
return ans;
}
int main()
{
NestedDict insidedict3{
new map<string, void*>{
{ "", (void*)new Value<int>(new int(1))}
}
};
NestedDict insidedict2{
new map<string, void*>{
{"d",(void*) new Value<int>(new int(3))},
{"e",(void*)&insidedict3}
}
};
NestedDict insidedict1{
new map<string, void*>{
{"a", (void*) new Value<int>(new int(2))},
{"b", (void*) new Value<int>(new int(3))},
{"c", (void*)&insidedict2}
}
};
map<string, void*> dict{ {"Key1",(void*) new Value<float>(new float(1.f))},{"Key2",(void*)&insidedict1}};
for (auto& in : flattenDictionary(dict))
std::cout << in.first << " : " << in.second << std::endl;
return 0;
}
Ввод
input: dict = {
"Key1" : "1.f",
"Key2" : {
"a" : "2",
"b" : "3",
"c" : {
"d" : "3",
"e" : {
"" : "1"
}
}
}
}
Вывод
/*
output
Key1 : 1065353216
Key2.a : 2
Key2.b : 3
Key2.c.d : 3
Key2.c.e. : 1
/*