【问题标题】:Better way to create nested array with count equals to children's total count更好的方法来创建嵌套数组的计数等于孩子的总数
【发布时间】:2020-07-10 00:13:16
【问题描述】:

我有类似的输入数据结构

const i = [
  { Time: "Breakfast", City: "Bangalore", Area: "Bellandur", count: 12 },
  { Time: "Breakfast", City: "Hyderabad", Area: "LBNagar", count: 19 },
  { Time: "Lunch", City: "Bangalore", Area: "Koramangala", count: 22 },
  { Time: "Dinner", City: "Hyderabad", Area: "Koti", count: 10 },
  { Time: "Dinner", City: "Bangalore", Area: "Bellandur", count: 16 },
  { Time: "Lunch", City: "Hyderabad", Area: "LBNagar", count: 28 },
  { Time: "Breakfast", City: "Bangalore", Area: "Bellandur", count: 11 },
  { Time: "Lunch", City: "Hyderabad", Area: "Koti", count: 24 },
  { Time: "Dinner", City: "Bangalore", Area: "Koramangala", count: 27 },
  { Time: "Breakfast", City: "Bangalore", Area: "Bellandur", count: 22 },
  { Time: "Breakfast", City: "Hyderabad", Area: "Manikonda", count: 11 },
  { Time: "Dinner", City: "Hyderabad", Area: "Manikonda", count: 10 },
  { Time: "Lunch", City: "Bangalore", Area: "Bellandur", count: 17 }
];

预期转换后的数据结构应该是嵌套数组,count 属性等于子元素的 count 值的总和

[
  {
    "d": "Breakfast",
    "count": 42,
    "children": [
      {
        "d": "Bangalore",
        "count": 12,
        "children": [
          {
            "d": "Bellandur",
            "count": 12,
            "children": []
          }
        ]
      },
      {
        "d": "Hyderabad",
        "count": 30,
        "children": [
          {
            "d": "LBNagar",
            "count": 19,
            "children": []
          },
          {
            "d": "Manikonda",
            "count": 11,
            "children": []
          }
        ]
      }
    ]
  },
  {
    "d": "Lunch",
    "count": 91,
    "children": [
      {
        "d": "Bangalore",
        "count": 39,
        "children": [
          {
            "d": "Koramangala",
            "count": 22,
            "children": []
          },
          {
            "d": "Bellandur",
            "count": 17,
            "children": []
          }
        ]
      },
      {
        "d": "Hyderabad",
        "count": 52,
        "children": [
          {
            "d": "LBNagar",
            "count": 28,
            "children": []
          },
          {
            "d": "Koti",
            "count": 24,
            "children": []
          }
        ]
      }
    ]
  },
  {
    "d": "Dinner",
    "count": 63,
    "children": [
      {
        "d": "Hyderabad",
        "count": 20,
        "children": [
          {
            "d": "Koti",
            "count": 10,
            "children": []
          },
          {
            "d": "Manikonda",
            "count": 10,
            "children": []
          }
        ]
      },
      {
        "d": "Bangalore",
        "count": 43,
        "children": [
          {
            "d": "Bellandur",
            "count": 16,
            "children": []
          },
          {
            "d": "Koramangala",
            "count": 27,
            "children": []
          }
        ]
      }
    ]
  }
]

为了达到上述效果,我有sn-p

const input = [
  { Time: "Breakfast", City: "Bangalore", Area: "Bellandur", count: 12 },
  { Time: "Breakfast", City: "Hyderabad", Area: "LBNagar", count: 19 },
  { Time: "Lunch", City: "Bangalore", Area: "Koramangala", count: 22 },
  { Time: "Dinner", City: "Hyderabad", Area: "Koti", count: 10 },
  { Time: "Dinner", City: "Bangalore", Area: "Bellandur", count: 16 },
  { Time: "Lunch", City: "Hyderabad", Area: "LBNagar", count: 28 },
  { Time: "Breakfast", City: "Bangalore", Area: "Bellandur", count: 11 },
  { Time: "Lunch", City: "Hyderabad", Area: "Koti", count: 24 },
  { Time: "Dinner", City: "Bangalore", Area: "Koramangala", count: 27 },
  { Time: "Breakfast", City: "Bangalore", Area: "Bellandur", count: 22 },
  { Time: "Breakfast", City: "Hyderabad", Area: "Manikonda", count: 11 },
  { Time: "Dinner", City: "Hyderabad", Area: "Manikonda", count: 10 },
  { Time: "Lunch", City: "Bangalore", Area: "Bellandur", count: 17 }
];

// convert nested array into map
// Ex: {Breakfast: { Bangalore: {Bellandur: 40 }, ... } ... }}}
const nestedMap = input.reduce((acc, v) => {
  if (!acc[v["Time"]]) {
    acc[v["Time"]] = {};
  }

  if (!acc[v["Time"]][v["City"]]) {
    acc[v["Time"]][v["City"]] = {};
  }

  if (!acc[v["Time"]][v["City"]][v["Area"]]) {
    acc[v["Time"]][v["City"]][v["Area"]] = v["count"];
  }

  return acc;
}, {});

const summer = (o, i) =>
  typeof o === "number"
    ? i + o
    : Object.values(o).reduce((acc, v) => acc + summer(v, i), 0);

const aggregator = o => {
  return typeof o === "number"
    ? []
    : Object.entries(o).map(([n, child]) => ({
        d: n,
        count: summer(child, 0),
        children: aggregator(child)
      }));
};

const result = aggregator(nestedMap);

console.log(JSON.stringify(result, undefined, 2));

认为我的 sn-p 工作完美,它涉及很多迭代。首先转换为 map 和一次迭代(summer 函数)以获取子项的计数,其他迭代(aggregator 函数)形成嵌套数组。

我正在寻找性能更好的解决方案。 提前致谢!

【问题讨论】:

标签: javascript recursion data-structures


【解决方案1】:

您可以采用更简洁的方法,使用嵌套键数组并搜索具有该级别值的对象。

然后添加计数并返回实际对象。

这种方法可以防止拖尾子数组

var data = [{ Time: "Breakfast", City: "Bangalore", Area: "Bellandur", count: 12 }, { Time: "Breakfast", City: "Hyderabad", Area: "LBNagar", count: 19 }, { Time: "Lunch", City: "Bangalore", Area: "Koramangala", count: 22 }, { Time: "Dinner", City: "Hyderabad", Area: "Koti", count: 10 }, { Time: "Dinner", City: "Bangalore", Area: "Bellandur", count: 16 }, { Time: "Lunch", City: "Hyderabad", Area: "LBNagar", count: 28 }, { Time: "Breakfast", City: "Bangalore", Area: "Bellandur", count: 11 }, { Time: "Lunch", City: "Hyderabad", Area: "Koti", count: 24 }, { Time: "Dinner", City: "Bangalore", Area: "Koramangala", count: 27 }, { Time: "Breakfast", City: "Bangalore", Area: "Bellandur", count: 22 }, { Time: "Breakfast", City: "Hyderabad", Area: "Manikonda", count: 11 }, { Time: "Dinner", City: "Hyderabad", Area: "Manikonda", count: 10 }, { Time: "Lunch", City: "Bangalore", Area: "Bellandur", count: 17 }],
    keys = ['Time', 'City', 'Area'],
    result = data
        .reduce((r, o) => {
            keys.reduce((p, k) => {
                var temp = (p.children = p.children || []).find(q => q.d === o[k]);
                if (!temp) p.children.push(temp = { d: o[k], count: 0 });
                temp.count += o.count;
                return temp;
            }, r);
            return r;
        }, { children: [] })
        .children;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多