首页 > 解决方案 > 对具有多个属性的 json 树进行排序

问题描述

我已经从一个普通的 json 准备了一个 json 树。但我需要对具有多个条件的树进行排序。例如在级别 1 我们有多个对象。我们需要使用 level 排序,然后使用 name 属性。

level 是一个数字,name 是一个字母数字。所以名称排序首先是字母,然后是数字

下面是输入的json

var inputJson = [
  {
  "level": "1",
  "leafFlag": "1",
  "path":"p123",
  "name":"food23"
},
  {
  "level": "1",
  "leafFlag": "1",
  "path":"r125",
  "name":"car1"
},
  {
  "level": "2",
  "leafFlag": "0",
  "path":"p123/p345",
  "name":"apple345"
},
 {
  "level": "2",
  "leafFlag": "1",
  "path":"p123/p095",
  "name":"123banana"
},
{
  "level": "3",
  "leafFlag": "0",
  "path":"p123/p095/p546",
  "name":"543"
},
{
  "level": "2",
  "leafFlag": "1",
  "path":"r125/yhes",
  "name":"tata78"
}
]

var output = [];

下面的代码准备 json 树。

我在这里尝试使用多个属性进行排序

inputJson = inputJson.sort((a, b) => (parseInt(a.level) > parseInt(b.level)) ? 1 : -1)
inputJson.forEach(v => {
    if (v.level == "1") {
    v.children = [];
    output.push(v);
  }
  else {
    pathValues = v.path.split("/");
    pathValues.pop();
    var node = null;
    var fullPath = "";
    pathValues.forEach(p => {
        fullPath = fullPath === "" ? p : fullPath + "/" + p;
        node = (node == null ? output : node.children).find(o => o.path === fullPath);
    })
    node.children = node.children || [];
    node.children.push(v);
  }
})

上面的输出:

var output = [
  {
    "level": "1",
    "leafFlag": "1",
    "path": "p123",
    "name": "food23",
    "children": [
      {
        "level": "2",
        "leafFlag": "0",
        "path": "p123/p345",
        "name": "apple"
      },
      {
        "level": "2",
        "leafFlag": "1",
        "path": "p123/p095",
        "name": "banana",
        "children": [
          {
            "level": "3",
            "leafFlag": "0",
            "path": "p123/p095/p546",
            "name": "grapes"
          }
        ]
      }
    ]
  },
  {
    "level": "1",
    "leafFlag": "1",
    "path": "r125",
    "name": "car",
    "children": [
      {
        "level": "2",
        "leafFlag": "1",
        "path": "r125/yhes",
        "name": "tata",
        "children": [
          {
            "level": "3",
            "leafFlag": "0",
            "path": "r125/yhes/sdie",
            "name": "Range Rover"
          }
        ]
      },
      {
        "level": "2",
        "leafFlag": "0",
        "path": "r125/theys",
        "name": "suzuki"
      }
    ]
  }
]

预期输出:

[
  {
    "level": "1",
    "leafFlag": "1",
    "path": "r125",
    "name": "car",
    "children": [
      {
        "level": "2",
        "leafFlag": "0",
        "path": "r125/theys",
        "name": "suzuki"
      },
      {
        "level": "2",
        "leafFlag": "1",
        "path": "r125/yhes",
        "name": "tata",
        "children": [
          {
            "level": "3",
            "leafFlag": "0",
            "path": "r125/yhes/sdie",
            "name": "Range Rover"
          }
        ]
      }
    ]
  },
  {
    "level": "1",
    "leafFlag": "1",
    "path": "p123",
    "name": "food",
    "children": [
      {
        "level": "2",
        "leafFlag": "0",
        "path": "p123/p345",
        "name": "apple"
      },
      {
        "level": "2",
        "leafFlag": "1",
        "path": "p123/p095",
        "name": "banana",
        "children": [
          {
            "level": "3",
            "leafFlag": "0",
            "path": "p123/p095/p546",
            "name": "grapes"
          }
        ]
      }
    ]
  }
]

我尝试了类似下面的东西

inputJson = inputJson.sort((a, b) => (parseInt(a.level) > parseInt(b.level)) ? 1 : -1 && a.name > b.name ? 1 ? -1)

标签: javascriptarraysjson

解决方案


您可以先按级别排序,然后按名称进行排序。

.sort((a, b) => a.level - b.level || a.name.localeCompare(b.name))

然后用排序的项目构建树。

var data = [{ level: "1", leafFlag: "1", path: "p123", name: "food" }, { level: "1", leafFlag: "1", path: "r125", name: "car" }, { level: "2", leafFlag: "0", path: "p123/p345", name: "apple" }, { level: "2", leafFlag: "1", path: "p123/p095", name: "banana" }, { level: "3", leafFlag: "0", path: "p123/p095/p546", name: "grapes" }, { level: "2", leafFlag: "1", path: "r125/yhes", name: "tata" }],
    result = data
        .sort((a, b) => a.level - b.level || a.name.localeCompare(b.name))
        .reduce((r, o) => {
            let p = o.path.split('/');
            p.pop();

            let target = p.reduce((t, _, i, p) => {
                var path = p.slice(0, i + 1).join('/'),
                    temp = (t.children = t.children || []).find(q => q.path === path);

                if (!temp) t.children.push(temp = { path }); // this is not necessary
                                                             // if all nodes are given
                return temp;
            }, { children: r });

            (target.children = target.children || []).push({ ...o });
            return r;
        }, []);

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


推荐阅读