Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • help instancing the Class in a loop/conditional

    Hi, I am heavy user of json files and LIBJSON Class ( from SSC) is my first choice to tackle it.



    Code:
    : scv[1,1]=`"{"title":"Title","data":"Data","foo": "Bar1"}"'
    : scv[2,1]=`"{"title":"Title","data":"Data","foo": "Bar2"}"'
    : scv
                                                       1
        +-------------------------------------------------+
      1 |  {"title":"Title","data":"Data","foo": "Bar1"}  |
      2 |  {"title":"Title","data":"Data","foo": "Bar2"}  |
        +-------------------------------------------------+
    
    : a=libjson()
    
    : root=a.parse(scv[1])
    
    : root->getString(("foo"),"")
      Bar1
    However, when include it in a loop, I get an error. I was not even able to close the loop bracket.

    Code:
    : for (i=1; i<=rows(scv); i++){
    > root=a.parse(scv[i])
    > if (root) { // continues if pointer value (root) that does not “points to nothing”
    > root->getString(("foo"),"");
    type mismatch:  -> (pointing to):  transmorphic found where pointer expected
    r(3000);
    In a conditional, I had to include another "}" to move on

    Code:
    : if (root) {
    > root->getString(("foo"),"")
    > }
    > }
      Bar1
    expression invalid
    r(3000);

    any clue? thanks, in advance

  • #2
    It seems as if you're trying to use this class (and pointers to its objects) in Mata's interactive mode. According to the help file, "Note that to use these examples interactively from the command line (or when embedded in an ado file), one must wrap them in a mata function body."

    When I do that, as shown in this code block,
    Code:
    version 18.0
    
    clear *
    
    local line_size `c(linesize)'
    set linesize 80
    
    mata:
    mata set matastrict on
    
    void function test(string colvector SCV) {
    
        class libjson scalar a
        // a = libjson()
    
        pointer (class libjson scalar) scalar root
        root = a.parse(SCV[1])
        string scalar foo
        foo = root->getString(("foo"),"")
        printf("Noniterative: %8s\n", foo)
    
        real scalar i
        for (i=1; i<=rows(SCV); i++){
            root = a.parse(SCV[i])
            if (root) {
                foo = root->getString(("foo"),"")
                printf("Iterative %1s %10s\n", strofreal(i), foo)
            }
        }
    }
    
    string colvector function Scv() {
        string colvector SCV
        SCV = J(2, 1, "")
        SCV[1]=`"{"title":"Title","data":"Data","foo": "Bar1"}"'
        SCV[2]=`"{"title":"Title","data":"Data","foo": "Bar2"}"'
        return(SCV)
    }
    
    end
    
    set linesize `line_size'
    
    mata: test(Scv())
    
    exit
    it runs fine with your example JSON object, without a hitch.

    .ÿ
    .ÿversionÿ18.0

    .ÿ
    .ÿclearÿ*

    .ÿ
    .ÿlocalÿline_sizeÿ`c(linesize)'

    .ÿsetÿlinesizeÿ80

    .ÿ
    .ÿmata:
    -------------------------------------------------ÿmataÿ(typeÿendÿtoÿexit)ÿ------
    :ÿmataÿsetÿmatastrictÿon

    :ÿ
    :ÿvoidÿfunctionÿtest(stringÿcolvectorÿSCV)ÿ{
    >ÿ
    >ÿÿÿÿÿclassÿlibjsonÿscalarÿa
    >ÿÿÿÿÿ//ÿaÿ=ÿlibjson()
    >ÿ
    >ÿÿÿÿÿpointerÿ(classÿlibjsonÿscalar)ÿscalarÿroot
    >ÿÿÿÿÿrootÿ=ÿa.parse(SCV[1])
    >ÿÿÿÿÿstringÿscalarÿfoo
    >ÿÿÿÿÿfooÿ=ÿroot->getString(("foo"),"")
    >ÿÿÿÿÿprintf("Noniterative:ÿ%8s\n",ÿfoo)
    >ÿ
    >ÿÿÿÿÿrealÿscalarÿi
    >ÿÿÿÿÿforÿ(i=1;ÿi<=rows(SCV);ÿi++){
    >ÿÿÿÿÿÿÿÿÿrootÿ=ÿa.parse(SCV[i])
    >ÿÿÿÿÿÿÿÿÿifÿ(root)ÿ{
    >ÿÿÿÿÿÿÿÿÿÿÿÿÿfooÿ=ÿroot->getString(("foo"),"")
    >ÿÿÿÿÿÿÿÿÿÿÿÿÿprintf("Iterativeÿ%1sÿ%10s\n",ÿstrofreal(i),ÿfoo)
    >ÿÿÿÿÿÿÿÿÿ}
    >ÿÿÿÿÿ}
    >ÿ}

    :ÿ
    :ÿstringÿcolvectorÿfunctionÿScv()ÿ{
    >ÿÿÿÿÿstringÿcolvectorÿSCV
    >ÿÿÿÿÿSCVÿ=ÿJ(2,ÿ1,ÿ"")
    >ÿÿÿÿÿSCV[1]=`"{"title":"Title","data":"Data","foo":ÿ"Bar1"}"'
    >ÿÿÿÿÿSCV[2]=`"{"title":"Title","data":"Data","foo":ÿ"Bar2"}"'
    >ÿÿÿÿÿreturn(SCV)
    >ÿ}

    :ÿ
    :ÿend
    --------------------------------------------------------------------------------

    .ÿ
    .ÿsetÿlinesizeÿ`line_size'

    .ÿ
    .ÿmata:ÿtest(Scv())
    Noniterative:ÿÿÿÿÿBar1
    Iterativeÿ1ÿÿÿÿÿÿÿBar1
    Iterativeÿ2ÿÿÿÿÿÿÿBar2

    .ÿ
    .ÿexit

    endÿofÿdo-file


    .

    Comment


    • #3
      you are right Joseph (as always). Help file mentions that (must wrap them in a mata function body).

      just for the sake of closing the topic and help others, below, is how to ignore bad-formed json objects ( note additional double quote in case 2) and continues the parsing loop.


      Code:
      scv=J(3,1,"")
      scv[1,1]=`"{"title":"Title","data":"Data","foo": "Bar1"}"'
      scv[2,1]=`"{"title":"Title","data":"Data","foo": "Ba""r2"}"'
      scv[3,1]=`"{"title":"Title","data":"Data","foo": "Bar3"}"'
      
      mata drop read()
      string colvector function read(string colvector SCV) {
          class libjson scalar a
          pointer (class libjson scalar) scalar root
          real scalar i
         string colvector saida
         saida=J(rows(SCV),1,"")
          for (i=1; i<=rows(SCV); i++){
              root = a.parse(SCV[i])
              if (root) saida[i] = root->getString(("foo"),"")
      }
      return(saida)
      }
      
      
      read(scv)
      
                1
          +--------+
        1 |  Bar1  |
        2 |        |
        3 |  Bar3  |
          +--------+

      Comment

      Working...
      X