【问题标题】:How to group data?如何对数据进行分组?
【发布时间】:2018-04-27 15:32:18
【问题描述】:

如何编写脚本,将数组的元素分组为数组数组(或数组对象),其中最后一个是按顺序分组的元素数组。

如果下一个元素 Id 是序列的一部分,则它属于 prev 组,否则将创建新数组,元素将落入其中。

如果元素 ID 高于前一个元素的 ID 大于 1 - 是相同的序列 = 当前数组。

如果元素 ID 高于前一个元素的 ID 大于 2 - 是下一个序列 = 下一个(新)数组。

如果元素相邻的 Id 来自所有方面都大于当前 Id - 当前元素将创建一个包含自身的数组,并且它的键将是它自己的 Id。

无论结果是数组还是对象 - 生成键很容易,但现在对我来说组元素很难。

您可以尝试用 JavaScript 编写,甚至可以使用 Lodash 库。

const data = [
{id: 1},
{id: 2},
{id: 3},
{id: 7},
{id: 9},
{id: 10},
{id: 12},
{id: 14},
{id: 15},
{id: 16}];

============================================

const result = [
0/"1-4": [
    {id: 1},
    {id: 2},
    {id: 3},
    {id: 4}],
1/"7": [
    {id: 7}],
2/"9-10": [
    {id: 9},
    {id: 10}],
3/"12": [
    {id: 12}],
4/"14-16": [
    {id: 14},
    {id: 15},
    {id: 16}]];

【问题讨论】:

  • 这是作业吗?
  • 否 - 这是大型工作任务的一部分,我在其中生成许多不同的数据,然后将其推送到 lib excelJs 以生成 xlsx 文件(报告)。一切都完成了,但这一刻对我来说很难。简单的 _.groupBy() 即使使用组合键进行分组我认为也是无助的。

标签: javascript ecmascript-6 lodash


【解决方案1】:

您可以使用 reduce 创建一个数组数组,其中下一个预期数字是当前项目 id 加一。

const data = [
  {id: 1},
  {id: 2},
  {id: 3},
  {id: 7},
  {id: 9},
  {id: 10},
  {id: 12},
  {id: 14},
  {id: 15},
  {id: 16}]
.sort((a,b)=>a.id-b.id)//make sure it is sorted by id
.reduce(
  ([result,nextNum],item)=>{//nextNum is the next expected number
    if(nextNum===undefined){//first time nextNum is undefined
      nextNum=item.id;//set nextNum to id of current item
      result.push([]);//add empty array
    }
    if(!(nextNum===item.id)){//current item id is not the expected next number
      result.push([]);//add empty array
    }
    result[result.length-1].push(item);//add item to last array of the array of arrays
    return [result,item.id+1];//next expected number is current item id + 1
  },
  [[],undefined]//initial values for result and nextNum
);
console.log(data)

【讨论】:

  • 哇!惊人的。谢谢。我会仔细看你代码的逻辑。
【解决方案2】:

您可以通过检查结果集的最后一个数组并检查最后一个对象的id 是否在所需范围内来使用单循环方法。

如果没有,则向结果集中添加一个新的空数组。稍后将实际对象推送到最后一个数组。

var data = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 7 }, { id: 9 }, { id: 10 }, { id: 12 }, { id: 14 }, { id: 15 }, { id: 16 }],
    grouped = data.reduce((r, o) => {
        var last = r[r.length - 1];
        if (!last || last[last.length - 1].id + 1 !== o.id) {
            r.push(last = []);
        }
        last.push(o);
        return r;
    }, []);

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

【讨论】:

    【解决方案3】:

    您可以使用链接的Array.reduce() 调用来创建所需的结构:

    const data = [{"id":1},{"id":2},{"id":3},{"id":7},{"id":9},{"id":10},{"id":12},{"id":14},{"id":15},{"id":16}];
    
    const arrayOfGroups = data
      .reduce((r, o, i) => {
        // if first or not sequence add new sub array
        if(!r.length || o.id !== data[i - 1].id + 1) r.push([]);
        
        // push to last sub array
        r[r.length - 1].push(o);
        
        return r;
      }, []);
      
    const objectOfGroups = arrayOfGroups.reduce((r, a, i) => {
        const start = a[0].id;
        const end = a[a.length - 1].id;
        // if start and end are equal, add just start (to main the order of insertion, start can be just a number)
        const key = start === end ? 
          `${i}/${start}` : `${i}/${start}-${end}`;
        
        r[key] = a;
      
        return r;
      }, {});
      
    console.log('arrayOfGroups', arrayOfGroups);
    
    console.log('objectOfGroups', objectOfGroups);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-11
      • 2021-02-11
      • 2015-05-15
      • 2018-12-06
      • 1970-01-01
      • 2019-02-09
      • 1970-01-01
      • 2022-01-22
      相关资源
      最近更新 更多