Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about making json object from file directory #1449

Closed
shanekoss opened this issue Jan 21, 2019 · 6 comments
Closed

Question about making json object from file directory #1449

shanekoss opened this issue Jan 21, 2019 · 6 comments

Comments

@shanekoss
Copy link

shanekoss commented Jan 21, 2019

I'm attempting to scan a folder and its subfolders to make a json object of the entire directory. So far I have this:

struct json_node;
using json_node_ptr = std::shared_ptr<json_node>;

struct json_node
{
    std::string id;
    std::vector<json_node_ptr> children;
    
    json_node(std::string _id)
    : id{ _id }
    {
    }
};

void to_json(nlohmann::json& j, const json_node_ptr& node)
{
    j = {{node->id, node->children}};
}

int main (int argc, char* argv[])
{
    std::vector<std::string> values = {"Folder 1","Folder 2","Folder 3","Folder 4","fileInFolder"};
    std::vector<json_node_ptr> parents;
    
    for(int i = 0; i < values.size(); i++)
    {
        if ( i == 0 ) {
            auto root = std::make_shared<json_node>(values[0]);
            parents.push_back(root);
        } else {
            parents.push_back(std::make_shared<json_node>(values[i]));
            parents[i-1]->children.push_back(parents[i]);
        }
    }
  
    nlohmann::json j = parents[0];
    std::cout << j.dump(2) << std::endl;
    
    
    return 0;
}

which works somewhat - it returns this:

{ "Folder 1": [ { "Folder 2": [ { "Folder 3": [ { "Folder 4": [ { "fileInFolder": [] } ] } ] } ] } ] }

and i'd like to have the last item as a string in the array - not another object - like so:

{ "Folder 1": [ { "Folder 2": [ { "Folder 3": [ { "Folder 4": [ "fileInFolder" ] } ] } ] } ] }

More importantly - not sure how to adapt this to handle multiple files (vectors) in the directory - (not just the single vector I have here) so that all files and folders are represented correctly in the object. Any pointers would be appreciated!

@request-info

This comment has been minimized.

@request-info request-info bot added the state: needs more info the author of the issue needs to provide more details label Jan 21, 2019
@nlohmann nlohmann added kind: question and removed state: needs more info the author of the issue needs to provide more details labels Jan 21, 2019
@nlohmann
Copy link
Owner

Is the json_node struct mandatory or just a vehicle to get toward the solution? That is, would it be sufficient if you had a json make_path(std::vector<std::string>) function?

@shanekoss
Copy link
Author

@nlohmann - thanks for the quick reply! That struct isn't mandatory at all. I wasn't sure how to approach it.

@nlohmann
Copy link
Owner

This seems so closed to a std::accumulate, but I did not get it to run. Another approach should be JSON Pointers, something like:

json j;
std::string p = "/Folder 1/0/Folder 2/0/Folder 3/0/Folder 4/0";
j[json::json_pointer(p)] = "fileInFolder";

This produces

{
    "Folder 1": [
        {
            "Folder 2": [
                {
                    "Folder 3": [
                        {
                            "Folder 4": [
                                "fileInFolder"
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

If this is what you want, then it should be easy to generate the string from the vector.

@nlohmann
Copy link
Owner

@shanekoss
Copy link
Author

@nlohmann - that is super helpful. Thanks for the info and speedy reply.

for anyone finding this - also helpful to add the initial file as array so you can push_back to it like so:

    std::string one ="/folder 1/0/folder 2/0/folder 3/0/folder 4";
    if(j[json::json_pointer(one)] == nullptr){
        j[json::json_pointer(one)] = {"fileToAdd"};
    }
    else{
        j[json::json_pointer(one)].push_back("fileToAdd");
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants