以特定格式重新排列Javascript数组

时间:2018-02-03 12:16:06

标签: javascript arrays sorting reduce

请注意,这不是重复的问题。

我很难找出从这个JSON数组开始的方法, 这是一个级别的数组,我们可以在“path”属性中拥有每个obj或元素的路径

[
  {
    "name" : "a-1",
    "path" : "a-1",
    "parent": ""
  },
  {
    "name" : "a-2",
    "path" : "a-1>a-2",
    "parent": "a-1"
  },
  {
    "name" : "a-3",
    "path" : "a-1>a-2>a-3",
    "parent": "a-2"
  },
  {
    "name" : "a-4",
    "path" : "a-1>a-4",
    "parent": "a-1"
  },
  {
    "name" : "b-1",
    "path" : "b-1",
    "parent": ""
  }
]

最终结果应该如下:

[
  {
    "attr": {
      "name": "a-1",
      "path": "a-1",
      "parent": ""
    },
    "children": [
      {
        "attr": {
          "name": "a-2",
          "path": "a-1>a-2",
          "parent": "a-1"
        },
        "children": [
          {
            "attr": {
              "name": "a-3",
              "path": "a-1>a-2>a-3",
              "parent": "a-2"
            }
          }
        ]
      },
      {
        "attr": {
          "name": "a-4",
          "path": "a-1>a-4",
          "parent": "a-1"
        }
      }
    ]
  },
  {
    "attr": {
      "name": "b-1",
      "path": "b-1",
      "parent": ""
    }
  }
]

我尝试使用带有Filter的父级并查找函数

theOneLevelArray.filter((elt, idx, arr) => {
   let parent = arr.find(e => e.componentItemNumber === elt.parentItemNumber);
   if (!parent) return true;
          (parent.children = parent.children || []).push(elt);
});

我还尝试使用循环然后在'split(“>”)'之后应用reduce函数的路径元素(此方法的代码非常麻烦,这就是我没有粘贴的原因)

2 个答案:

答案 0 :(得分:1)

对于使用给定路径,您可以通过检查给定的path和临时结果来采用迭代方法。

这需要有序数据。

var data = [{ name: "a-1", path: "a-1", parent: "" }, { name: "a-2", path: "a-1>a-2", parent: "a-1" }, { name: "a-3", path: "a-1>a-2>a-3", parent: "a-2" }, { name: "a-4", path: "a-1>a-4", parent: "a-1" }, { name: "b-1", path: "b-1", parent: "" }],
    tree = [];

data.forEach(function (object) {
    object.path.split('>').reduce(function (level, key) {
        var temp = level.find(({ attr: { name } }) => key === name);
        if (!temp) {
            temp = { attr: object, children: [] };
            level.push(temp);
        }
        return temp.children;
    }, tree);
});

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

使用parent属性和临时obejct作为对具有相同名称的对象的引用的另一种方法。

这也适用于未分类的数据。

var data = [{ name: "a-1", path: "a-1", parent: "" }, { name: "a-2", path: "a-1>a-2", parent: "a-1" }, { name: "a-3", path: "a-1>a-2>a-3", parent: "a-2" }, { name: "a-4", path: "a-1>a-4", parent: "a-1" }, { name: "b-1", path: "b-1", parent: "" }],
    tree = function (data, root) {
        var r = [], o = {};
        data.forEach(function (attr) {
            var temp = { attr };
            if (o[attr.name] && o[attr.name].children) {
                temp.children = o[attr.name] && o[attr.name].children;
            }
            o[attr.name] = temp;
            if (attr.parent === root) {
                r.push(temp);
            } else {
                o[attr.parent] = o[attr.parent] || {};
                o[attr.parent].children = o[attr.parent].children || [];
                o[attr.parent].children.push(temp);
            }
        });
        return r;
    }(data, '');

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

简单的递归方法:

function getNodes(parentName) {
  const mapNode = (node) => {
    const children = getNodes(node.name);
    return children.length > 0 ?
      { attr: node, children } :
      { attr: node };
  };

  return source
     .filter(n => n.parent === parentName)
     .map(mapNode);
}

调用:getNodes('')

假设source是原始数组。