代码之家  ›  专栏  ›  技术社区  ›  Dmitry Bubnenkov

在递归中获得堆栈溢出

  •  0
  • Dmitry Bubnenkov  · 技术社区  · 5 年前

    我想从JSON生成INSERT语句。我在递归方面遇到的问题(在获取嵌套元素的部分)。看来我越来越紧张了。

    import 'dart:convert';
    
    main() {
      Map jsonMap = jsonDecode(
          '{"id":"1","name":"sample","Lots":[{"id":"1","title":"books","objs":[{"book":"name"}]}]}');
    
      KVToTableInsert(String tablename, Map jsonMap) {
        List<String> insertNoticeKeys = [];
        List<String> insertNoticeValues = [];
        jsonMap.forEach((key, value) {
          if (value is List) // nested
          {
            KVToTableInsert(key, jsonMap); // if comment this line all work
          } else {
            insertNoticeKeys.add(key);
            insertNoticeValues.add(value);
          }
        });
    
        String sql = "INSERT INTO $tablename (" +
            insertNoticeKeys.map((e) => '"$e"').join(', ') +
            ") VALUES (" +
            insertNoticeValues.map((e) => "'$e'").join(', ') +
            ")";
        print(sql);
      }
    
      KVToTableInsert("RootTable", jsonMap);
    }
    

    我希望得到3个插入状态:

    INSERT INTO RootTable ("id", "name") VALUES ('1', 'sample')
    
    INSERT INTO Lots ("id", "title") VALUES ('1', 'books')
    
    INSERT INTO Objs ("book") VALUES ('name')
    

    但我开始迷恋这款应用。

    0 回复  |  直到 5 年前
        1
  •  1
  •   halfer Jatin Pandey    4 年前

    代码中有一个小问题,基本上是在这一部分:

    if (value is List){
      KVToTableInsert(key, jsonMap); // if comment this line all work
    }
    

    如果你仔细观察,看看你的眼睛 KVToTableInsert ,你在传递论点 Map list .这使你的递归失败。

    您需要做的是将数组中的项传递到 KVToTableInsert ,这将按预期工作

    最终解决方案

    // taking your jsonMap directly, and not decoding it
    void main() {
      Map jsonMap = {
        "id":"1",
        "name":"sample",
        "Lots":[
          {
            "id": "1",
            "title":"books",
            "objs":[
              {
                "book":"name"
              }
            ]
          }
        ]
      };
    
      void KVToTableInsert(tablename, jsonMap){
        List<String> insertNoticeKeys = [];
        List<String> insertNoticeValues = [];
        jsonMap.forEach((key,value){
          if (value is List) 
          {
            // Here is the magic, you need to iterate over your list, and pass MAP, not LIST
            value.forEach((item){ KVToTableInsert(key, item);});
          } else {
            insertNoticeKeys.add(key);
            insertNoticeValues.add(value);
          }
        });
        
        String sql = "INSERT INTO $tablename (" +
            insertNoticeKeys.map((e) => '"$e"').join(', ') +
            ") VALUES (" +
            insertNoticeValues.map((e) => "'$e'").join(', ') +
            ")";
        print(sql);
      }
      
      KVToTableInsert("Rootable", jsonMap);
    }
    

    输出

    INSERT INTO objs ("book") VALUES ('name')
    INSERT INTO Lots ("id", "title") VALUES ('1', 'books')
    INSERT INTO Rootable ("id", "name") VALUES ('1', 'sample')
    

    另外,看看 Dart Programming Language Naming Conventions ,这是一个很好的练习 lowerCamelCase 函数/方法名。