【问题标题】:JavaScript - Group Array by value and upto two levelsJavaScript - 按值和最多两个级别对数组进行分组
【发布时间】:2020-06-16 19:27:17
【问题描述】:

考虑以下输入数组:

var input = [{
  "index": "1",
  "location": "London",
  "source": "1-source"
}, {
  "index": "1",
  "location": "New York",
  "source": "1-souce"
}, {
  "index": "1",
  "location": "London",
  "source": "2-source"
}, {
  "index": "2",
  "location": "London",
  "source": "3-source"
}, {
  "index": "2",
  "location": "London",
  "source": "4-source"
}, {
  "index": "1",
  "location": "Japan",
  "source": "1-source"
}, {
  "index": "3",
  "location": "London",
  "source": "5-source"
}, {
  "index": "3",
  "location": "London",
  "source": "6-source"
}, {
  "index": "4",
  "location": "London",
  "source": "7-source"
}, {
  "index": "4",
  "location": "London",
  "source": "8-source"
}, {
  "index": "2",
  "location": "Japan",
  "source": "2-souce"
}, {
  "index": "1",
  "location": "New York",
  "source": "2-source"
}, {
  "index": "2",
  "location": "Japan",
  "source": "3-souce"
}, {
  "index": "2",
  "location": "Japan",
  "source": "4-source"
}, {
  "index": "3",
  "location": "Japan",
  "source": "Press Pumps"
}, {
  "index": "2",
  "location": "New York",
  "source": "3-source"
}, {
  "index": "3",
  "location": "Japan",
  "source": "Camera01"
}]

它应该被分组到以下数组中:

var output = [{
  "name": "London",
  "children": [{
          "name": "1",
          "children": [{
              "name": "1-source"
          }, {
              "name": "2-source"
          }]
      },
      {
          "name": "2",
          "children": [{
              "name": "3-source"
          }, {
              "name": "4-source"
          }]
      },
      {
          "name": "3",
          "children": [{
              "name": "5-source"
          }, {
              "name": "6-source"
          }]
      },
      {
          "name": "4",
          "children": [{
              "name": "7-source"
          }, {
              "name": "8-source"
          }]
      }
  ]
},
{
  "name": "New York",
  "children": [{
          "name": "1",
          "children": [{
              "name": "1-souce"
          }, {
              "name": "2-source"
          }]
      },
      {
          "name": "2",
          "children": [{
              "name": "3-source"
          }]
      }
  ]
},
{
  "name": "Japan",
  "children": [{
          "name": "1",
          "children": [{
              "name": "1-source"
          }]
      },
      {
          "name": "2",
          "children": [{
              "name": "2-souce"
          }, {
              "name": "3-souce"
          }, {
              "name": "4-source"
          }]
      },
      {
          "name": "3",
          "children": [{
              "name": "Press Pumps"
          }, {
              "name": "Camera01"
          }]
      }
  ]
}
];

我尝试过的:

var groupBy = function (xs, key) {
  return xs.reduce(function (rv, x) {        
    var tmp = rv.find(r => r.name == x[key]) || { name: x[key], children: []};
    if (tmp.children.length == 0) {
      rv.push(tmp);
    }    
    tmp.children.push(x);
    return rv;
  }, []);
};
var result = groupBy(input, 'location');
result.forEach(function(r){
  //console.log(r);
  r.children = groupBy(r.children, 'index');
  r.children.forEach(function(c){
    //console.log(c);
    c.children = groupBy(c.children,'source');
    c.children.forEach(function(f){
      delete f.children;
      //console.log(f);
    })
  })
});
console.log(result);

我认为 forEach 有点矫枉过正!?我只是想知道是否有更好的方法来做到这一点。另外,你认为我应该尝试像递归这样的东西吗?

【问题讨论】:

  • 我开始玩这个,现在我的意大利面准备好了!也许它会帮助你走上正确的道路。 jsfiddle.net/mitya33/Lbp42ufn/10
  • @Utkanos 谢谢!最后一级没有分组。请将您的结果与输出进行比较。
  • 我没有说我已经完成了——我说我开始玩它了。如果您了解我的方法是如何工作的,这应该足以让您走上正确的道路。
  • @Utkanos 好的,是的,我只是点击了 jsfiddle,我并没有真正阅读您输入的内容,是的,它很有帮助,非常感谢!
  • 开心.......

标签: javascript arrays json performance grouping


【解决方案1】:

希望对你有帮助。

var res = input.reduce((res, { index, location, source }) => {
  var place = res.find(p => p.name === location)
  if (!place) {
    place = { name: location, children: [] }
    res.push(place)
  }
  var child = place.children.find(ch => ch.name === index)
  if (!child) {
    child = { name: index, children: [] }
    place.children.push(child)
  }
  child.children.push({ name: source })
  return res
}, [])

【讨论】:

    【解决方案2】:

    您可以通过一次组合树结构然后将所有内容放在一起来通过数组(多个 groupBy/find)保存多个查找。这些任务可以以 CPU 成本“就地”解决,也可以通过内存成本映射来解决。

    /*
      maps tree structure like:
      {
        "London": {
          "1": [{"name": "2-source"}]
        }
      }
    */
    const locMap = {};
    for (item of input) {
      locMap[item.location] = locMap[item.location] || {};
      locMap[item.location][item.index] = locMap[item.location][item.index] || [];
      locMap[item.location][item.index].push({name: item.source});
    }
    
    // composes desired object from tree structure above
    const output = Object.entries(locMap).map(([locName, idxMap]) => {
      return {
        name: locName,
        children: Object.entries(idxMap).map(([index, sources]) => {
          return {
            name: index,
            children: sources
          }
        })
      }
    })
    
    console.log(output);
    <script>
    var input = [{
      "index": "1",
      "location": "London",
      "source": "1-source"
    }, {
      "index": "1",
      "location": "New York",
      "source": "1-souce"
    }, {
      "index": "1",
      "location": "London",
      "source": "2-source"
    }, {
      "index": "2",
      "location": "London",
      "source": "3-source"
    }, {
      "index": "2",
      "location": "London",
      "source": "4-source"
    }, {
      "index": "1",
      "location": "Japan",
      "source": "1-source"
    }, {
      "index": "3",
      "location": "London",
      "source": "5-source"
    }, {
      "index": "3",
      "location": "London",
      "source": "6-source"
    }, {
      "index": "4",
      "location": "London",
      "source": "7-source"
    }, {
      "index": "4",
      "location": "London",
      "source": "8-source"
    }, {
      "index": "2",
      "location": "Japan",
      "source": "2-souce"
    }, {
      "index": "1",
      "location": "New York",
      "source": "2-source"
    }, {
      "index": "2",
      "location": "Japan",
      "source": "3-souce"
    }, {
      "index": "2",
      "location": "Japan",
      "source": "4-source"
    }, {
      "index": "3",
      "location": "Japan",
      "source": "Press Pumps"
    }, {
      "index": "2",
      "location": "New York",
      "source": "3-source"
    }, {
      "index": "3",
      "location": "Japan",
      "source": "Camera01"
    }]
    </script>

    【讨论】:

      猜你喜欢
      • 2020-09-19
      • 2021-11-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多