将路径数组转换为对象数组分组

时间:2018-07-11 14:56:45

标签: javascript arrays

我确实找到了这个问题How to convert an array of paths into JSON structure?,但是,我似乎无法操纵答案来实现自己想要的目标。

我有一系列的Paths,我想将其转换为易于在客户端上使用的对象。

[
    "\\Folder\file.xlsx",
    "\\Folder\file2.xlsx",
    "\\Folder\file3.docx",
    "\\Folder\Folder2\file4.xlsx",
    "\\Folder\Folder2\Folder3\file5.xlsx",
    "\\Folder\Folder2\file6.xlsx",
    "\\Folder\Folder4\file7.pdf"
    "\\Folder\Folder4\Folder5\1. file8.pdf"
]

我正在尝试获得看起来像这样的输出:

output = {
    Folder: {
        {
            file: file.xlsx,
            path: \\Folder\file.xlsx

        }, 
        {
            file: file2.xlsx,
            path: \\Folder\file2.xlsx
        }, 
        {
            file: file3.xlsx,
            path: \\Folder\file3.docx
        }
        Folder2: {

                {
                    file: file4.xlsx,
                    path: \\Folder\Folder2\file4.xlsx
                }, 
                Folder3:{

                        {
                            file: file5.xlsx,
                            path: \\Folder\Folder2\Folder3\file5.xlsx
                        },

                },
                {
                    file: file6.docx,
                    path: \\Folder\Folder2\file6.xlsx
                } 
        },
        Folder4: {
            {
                file: file7.pdf,
                path: \\Folder\Folder4\file7.pdf
            },
            Folder5: {
                {
                    file: 1. file8.pdf,
                    path: \\Folder\Folder4\Folder5\1. file8.pdf
                },
            }
        }
    }
}

目前,我有这个可以给我空的对象,但没有路径:

        var output = {};
        var current;

        for (var a = 0; a < files.length; a++) {
            var s = files[a].split("\\");
            // console.log("s ===> ", s);
            current = output;

            for (var i = 0; i < s.length; i++) {
                if (s[i] != "") {
                    if (current[s[i]] == null) {
                        current[s[i]] = {};
                    } else {
                        current = current[s[i]];
                    }
                }
            }
        }

但是它并没有完全返回我想要的东西。我不太确定是否有map或reduce这样的函数可以帮助解决这个问题,因为我对Java还是很陌生。

如果有人可以将我指向正确的方向,那就太好了。

2 个答案:

答案 0 :(得分:3)

这里是mapreduce的示例:)

请注意,您的预期输出无效,因此我对最自然的方式做了一些调整。

const files = [
    "\\Folder\\file.xlsx",
    "\\Folder\\file2.xlsx",
    "\\Folder\\file3.docx",
    "\\Folder\\Folder2.xlsx",
    "\\Folder\\Folder2\\file4.xlsx",
    "\\Folder\\Folder3\\file5.xlsx",
    "\\Folder\\Folder3\\file6.docx",
    "\\Folder\\Folder4\\file7.pdf"
];

const result = files.map(filePath => 
({
  path: filePath, 
  file: filePath.substring(filePath.lastIndexOf('\\')+1)
})).reduce((acc, item) => {
  const folderPath = item.path.substring(0, item.path.length-(item.file.length+1));
  const folder = folderPath.substring(folderPath.lastIndexOf('\\')+1);
  acc[folder] = acc[folder] || [];
  acc[folder].push(item);
  return acc;
}, {});

console.log(result);

这里有个小解释:

首先,您将文件map reduce到期望的对象,然后用map重新组织它们!您同时用管道reduce#include <boost/msm/back/state_machine.hpp> #include <boost/msm/front/state_machine_def.hpp> namespace msm = boost::msm; namespace mpl = boost::mpl; struct Event {}; class Sm_ : public msm::front::state_machine_def<Sm_> { public: using Me = Sm_; struct First : public msm::front::state<> {}; using initial_state = First; struct Second : public msm::front::state<> {}; void trans(const Event& /*e*/) {} struct transition_table : public mpl::vector< a_row<First, Event, Second, &Me::trans> > {}; }; using Sm = msm::back::state_machine<Sm_>; // broken one enum class Side : char { Buy = 0, Sell = 1 }; template <Side side> class TSm_ : public msm::front::state_machine_def<TSm_<side>> { public: using Me = TSm_<side>; using Base = msm::front::state_machine_def<Me>; using Base::a_row; struct First : public msm::front::state<> {}; using initial_state = First; struct Second : public msm::front::state<> {}; void trans(const Event& /*e*/) {} struct transition_table : public mpl::vector< a_row<First, Event, Second, &Me::trans> // compilation is failed here > {}; }; template <Side side> using TSm = msm::back::state_machine<TSm_<side>>; 进行作业!

答案 1 :(得分:1)

这将以递归方式工作,因此您可以像\\Folder\\........\\Folder10\\file.doc一样深入;

const files = [
  "\\Folder\\file.xlsx",
  "\\Folder\\file2.xlsx",
  "\\Folder\\file3.docx",
  "\\Folder\\Folder2\\file4.xlsx",
  "\\Folder\\Folder2\\Folder3\\file5.xlsx",
  "\\Folder\\Folder2\\file6.xlsx",
  "\\Folder\\Folder4\\file7.pdf",
  "\\Folder\\Folder4\\Folder5\\1. file8.pdf"
];

const result = files.reduce((obj, p) => {

  let temp = obj;
  p.split('\\').forEach((d, i, arr) => {
    if (!d) return;
    if (i === 0) return;
    if (i === arr.length - 1) {
      temp['files'] = [...(temp['files'] || []), {
        file: d,
        path: p
      }];
    } else if (!temp[d]) {
      temp[d] = {};
    }
    temp = temp[d];
  });

  return obj;
}, {});

console.log(result);

文件夹的直接文件位于files数组中。

{
  "Folder": {
    "files": [
      {
        "file": "file.xlsx",
        "path": "\\Folder\\file.xlsx"
      },
      {
        "file": "file2.xlsx",
        "path": "\\Folder\\file2.xlsx"
      },
      {
        "file": "file3.docx",
        "path": "\\Folder\\file3.docx"
      }
    ],
    "Folder2": {
      "files": [
        {
          "file": "file4.xlsx",
          "path": "\\Folder\\Folder2\\file4.xlsx"
        },
        {
          "file": "file6.xlsx",
          "path": "\\Folder\\Folder2\\file6.xlsx"
        }
      ],
      "Folder3": {
        "files": [
          {
            "file": "file5.xlsx",
            "path": "\\Folder\\Folder2\\Folder3\\file5.xlsx"
          }
        ]
      }
    },
    "Folder4": {
      "files": [
        {
          "file": "file7.pdf",
          "path": "\\Folder\\Folder4\\file7.pdf"
        }
      ],
      "Folder5": {
        "files": [
          {
            "file": "1. file8.pdf",
            "path": "\\Folder\\Folder4\\Folder5\\1. file8.pdf"
          }
        ]
      }
    }
  }
}