Open jkrumbiegel opened 3 years ago
If you return a new FileTree
it will be appended to the matching for both map
and mapsubtrees
. The function maketree
can be useful for this, but one can also call the FileTree
constructor as is.
Example with the former:
julia> ft= maketree(["a" => [(name="b", value=1), (name="c", value=2)]])
./
└─ a/
├─ b (Int64)
└─ c (Int64)
julia> mapsubtrees(ft, r"b") do node
return ft
end
./
└─ a/
├─ a/
│ ├─ b (Int64)
│ └─ c (Int64)
└─ c (Int64)
``´
In my case this didn't quite work because I don't want to replace a File
with a FileTree
of one folder with four files, but basically just with the four files in the same folder that the file was in. This currently adds a "./" node which I guess can cause problems when using glob patterns etc? I understand why it happens, but it would be cool if the "same level" tree could be flattened.
MWE:
julia> tree = maketree(["folder" => [(name = "file", value = "value")]])
./
└─ folder/
└─ file (5-codeunit String)
julia> map(tree, dirs = false) do file
maketree([(name = "file $i", value = i) for i in 1:4])
end
./
└─ folder/
└─ ./
├─ file 1 (Int64)
├─ file 2 (Int64)
├─ file 3 (Int64)
└─ file 4 (Int64)
Hi,
You can specify the name of the root of you put is as the very first argument (note that the array starts at after the =>
)
julia> newtree = map(tree, dirs = false) do file
maketree(name(file) => [(name = "file $i", value = i) for i in 1:4])
end
./
└─ folder/
└─ file/
├─ file 1 (Int64)
├─ file 2 (Int64)
├─ file 3 (Int64)
└─ file 4 (Int64)
If you don't want the file
intermediate level I think you need to rewrite the map so it maps all nodes and then replace "folder" instead of "file". Alternatively, you can just mv after:
julia> mv(newtree, r"file/", s"")
./
└─ folder/
├─ file 1 (Int64)
├─ file 2 (Int64)
├─ file 3 (Int64)
└─ file 4 (Int64)
Fwiw, here is the function I use in my own code to do this in one go. As you can tell from the name and usage, it requires one to think a bit carefully when using it:
julia> mapleavesparent(f, ft) = map(ft) do node
# NOTE: Only applies when all children are files. What does the user want to do if there is a mix of Files and FileTrees?
eltype(children(node)) === File ? f(node) : node
end;
julia> mapleavesparent(tree) do node
# Just don't forget that "file" is the child of node, not node itself
maketree(name(node) => [(name = "file $i", value = i) for i in 1:4])
end
./
└─ folder/
├─ file 1 (Int64)
├─ file 2 (Int64)
├─ file 3 (Int64)
└─ file 4 (Int64)
I think
./
└─ folder/
└─ ./
├─ file 1 (Int64)
├─ file 2 (Int64)
├─ file 3 (Int64)
└─ file 4 (Int64)
Should behave equivalently to
./
└─ folder/
├─ file 1 (Int64)
├─ file 2 (Int64)
├─ file 3 (Int64)
└─ file 4 (Int64)
Or maybe there should be a function which turns the former into the latter.
I couldn't quite figure out how to do this: I have a bunch of audio files and want to do four transformations on each of them, resulting in four separate files per original file. I don't think I can map over the files and return multiple new files each, or maybe that works with mapsubtrees? I'm not sure