Loop to a filesystem structure in my object to get all the files

后端 未结 4 1443
孤独总比滥情好
孤独总比滥情好 2021-01-17 01:16

I get a Javascript Object from my server, which depicts a filesystem. Now I want to get the path of all files in the system, e.g. the endpoints of the tree.

File str

相关标签:
4条回答
  • 2021-01-17 01:33

    working solution:

    var json = {"path":"/pages/services/project", "is_dir":true, "children":[{"path":"/pages/services/project/headline","is_dir":false,"children":[]},{"path":"/pages/services/project/text","is_dir":false,"children":[]},
    {"path":"/pages/services/project/test/","is_dir":true,"children":[{"path":"/pages/services/project/test/text","is_dir":false,"children":[]},
    {"path":"/pages/services/project/test/picture","is_dir":false,"children":[]}]}]};
    
    json.children.forEach(function (child) {
        goToDeepestPoint(child);
    });
    
    
    
    function goToDeepestPoint(node) {
        if (node.is_dir){
          for(var i=0;i<node.children.length;i++){
            goToDeepestPoint(node.children[i]);
          }
        }        
        else {
            out(node.path);
        }
    }
    
    function out()
    {
        var args = Array.prototype.slice.call(arguments, 0);
        document.getElementById('output').innerHTML += args.join(" ") + "\n";
    }
    
    0 讨论(0)
  • 2021-01-17 01:34

    var json = {"path":"/pages/services/project", "is_dir":true, "children":[{"path":"/pages/services/project/headline","is_dir":false,"children":[]},{"path":"/pages/services/project/text","is_dir":false,"children":[]},
    {"path":"/pages/services/project/test/","is_dir":true,"children":[{"path":"/pages/services/project/test/text","is_dir":false,"children":[]},
    {"path":"/pages/services/project/test/picture","is_dir":false,"children":[]}]}]};
    
    function getPaths(obj){
        let foundPaths = [];
        if(obj.children.length > 0){
            obj.children.forEach(function (element){
               let childPaths = getPaths(element);
               foundPaths = foundPaths.concat(childPaths);
            });
            return foundPaths;
       } else {
          foundPaths.push(obj.path);
          return foundPaths;
       }
    }
    
    let paths = getPaths(json);
    
    document.getElementById('output').innerHTML += paths.join("\n");
    <pre id="output"></pre>

    0 讨论(0)
  • 2021-01-17 01:40

    I was busy having a play with your original question and got this working:

    goToDeepestPoint(json);
    
    function goToDeepestPoint(node) {
        if (node.is_dir)
            node.children.forEach(function (child) {
        goToDeepestPoint(child);
    });
        else 
            return out(node.path);
    }
    

    May not be appropriate in the light of your edit, but shame to waste it!

    0 讨论(0)
  • 2021-01-17 01:47

    I'll share my answer because it's relevant to a thing I've been working on at the moment - it takes a more functional approach because that just happens to be what I've been studying

    Persistent iterators

    JavaScript's stateful iterators make me sad, so we can implement a persistent iterator interface using our own Yield and Return types. A Memo type is used but that is merely an optimisation detail.

    const Memo = (f, memo) => () =>
      memo === undefined
        ? (memo = f (), memo)
        : memo
    
    const Yield = (value, next = Return) =>
      ({ done: false, value, next: Memo (next) })
      
    const Return = value =>
      ({ done: true, value })
      
    // example use
    const ArrayIterator = (xs = []) =>
      xs.length === 0
        ? Return ()
        : Yield (xs [0], () => ArrayIterator (xs.slice (1)))
        
    const it =
      ArrayIterator ([1,2,3])
    
    console.log (it.value) // 1
    console.log (it.value) // 1
    console.log (it.next () .value) // 2
    console.log (it.next () .value) // 2

    Now, if necessary to create an adapter to interoperate with JavaScript's native generators, we can create a Generator type

    Admittedly, this is not super interesting, but it does demonstrate the necessary functionality

    const Generator = function* (it = Return ())
      {
        while (it.done === false)
          (yield it.value, it = it.next ())
        return it.value
      }
    
    Array.from (Generator (ArrayIterator ([1,2,3])))
    // => [1,2,3]
    

    Our persistent iterators open the door for more exciting things like this tho

    const MappedIterator = (f = x => x, it = Return ()) =>
      it.done
        ? Return ()
        : Yield (f (it.value), () => MappedIterator (f, it.next ()))
    
    const ConcatIterator = (x = Return (), y = Return) =>
      x.done
        ? y ()
        : Yield (x.value, () => ConcatIterator (x.next (), y))
    
    const it =
      MappedIterator (x => x * x, ArrayIterator ([1,2,3]))
    
    Array.from (Generator (it))                      // => [ 1, 4, 9 ]
    Array.from (Generator (ConcatIterator (it, it))) // => [ 1, 4, 9, 1, 4, 9 ]
    

    Pure expression

    Our persistent iterators give us a neat way to express a potentially complex traversal of our data structure. Here's one way we could write your tree iterator as a pure expression

    const FlatMappedIterator = (f, it = Return ()) =>
      it.done
        ? Return ()
        : ConcatIterator (f (it.value), () => FlatMappedIterator (f, it.next ()))
    
    const MyTreeIterator = node =>
      node === undefined
        ? Return ()
        : node.is_dir
          ? FlatMappedIterator (MyTreeIterator, ArrayIterator (node.children))
          : Yield (node.path)
    

    Of course the answer is incomplete without a demonstration of working code

    const Memo = (f, memo) => () =>
      memo === undefined
        ? (memo = f (), memo)
        : memo
    
    const Yield = (value, next = Return) =>
      ({ done: false, value, next: Memo (next) })
      
    const Return = value =>
      ({ done: true, value })
    
    // -------------------------------------------------------------------
    const ArrayIterator = (xs = []) =>
      xs.length === 0
        ? Return ()
        : Yield (xs [0], () => ArrayIterator (xs.slice (1)))
        
    const ConcatIterator = (x = Return (), y = Return) =>
      x.done
        ? y ()
        : Yield (x.value, () => ConcatIterator (x.next (), y))
        
    const FlatMappedIterator = (f, it = Return ()) =>
      it.done
        ? Return ()
        : ConcatIterator (f (it.value), () => FlatMappedIterator (f, it.next ()))
    
    const Generator = function* (it = Return ())
      {
        while (it.done === false)
          (yield it.value, it = it.next ())
        return it.value
      }
      
    // -------------------------------------------------------------------
    const MyTreeIterator = node =>
      node === undefined
        ? Return ()
        : node.is_dir
          ? FlatMappedIterator (MyTreeIterator, ArrayIterator (node.children))
          : Yield (node.path)
    
    const data =
      {path:'/pages/services/project', is_dir:true, children:[
        {path:'/pages/services/project/headline',is_dir:false,children:[]},
        {path:'/pages/services/project/text',is_dir:false,children:[]},
        {path:'/pages/services/project/test/',is_dir:true,children:[
          {path:'/pages/services/project/test/text',is_dir:false,children:[]},
          {path:'/pages/services/project/test/picture',is_dir:false,children:[]}
        ]}
      ]}
    
    // -------------------------------------------------------------------
    // example use of generator around our custom persistent iterator
    for (const path of Generator (MyTreeIterator (data)))
      {
        const elem = document.createElement ('p')
        elem.textContent = path
        document.body.appendChild (elem)
      }

    0 讨论(0)
提交回复
热议问题