怎么对一组数据按照某个特定字段进行分组?

发布于 2022-09-07 15:55:08 字数 1393 浏览 26 评论 0

比如我有一组数据

[
  {
    'time': '2018-03-01',
    'data': 1,
  },
  {
    'time': '2018-02-02',
    'data': 2,
  },
  {
    'time': '2018-01-01',
    'data': 3,
  },
  {
    'time': '2017-12-01',
    'data': 4,
  }, 
  {
    'time': '2017-11-02',
    'data': 5,
  }, 
  {
    'time': '2016-10-01',
    'data': 6,
  },
  {
    'time': '2016-9-01',
    'data': 7,
  }    
]

实际业务场景是对这组数据进行分组,每5条一组 但是这5条还要根据他们的日期年份分小组

比如上面这7条分出来结果就是:

[
  {
    section: 1,
    sectionDatas: [
      {
        date: '2018',
        datas: [
          {
            'time': '2018-03-01',
            'data': 1,
          },
          {
            'time': '2018-02-02',
            'data': 2,
          },
          {
            'time': '2018-01-01',
            'data': 3,
          }
        ]
      },
      {
        date: '2017',
        datas: [
          {
            'time': '2017-12-01',
            'data': 4,
          }, 
          {
            'time': '2017-11-02',
            'data': 5,
          }
        ]
      }
    ]
  },
  {
    section: 2,
    sectionDatas: [
      {
        date: '2016',
        datas: [
          {
            'time': '2016-10-01',
            'data': 6,
          },
          {
            'time': '2016-9-01',
            'data': 7,
          } 
        ]
      }
    ]
  } 
]

这个算法该怎么写呢。。求指教

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忘年祭陌 2022-09-14 15:55:08

步骤

*第一步:排序,时间从近到远
*第二步:分割,将数组分成5个一组,返回新数组
*第三步:抽离,将相同时间抽离出来组成要求上的数据格式

代码

第一步:排序

    var compare = function (prop) {
        return function (obj1, obj2) {
            var val1 = obj1[prop];
            var val2 = obj2[prop];
            if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
                val1 = Number(val1);
                val2 = Number(val2);
            }
            if (val1 < val2) {
                return 1;
            } else if (val1 > val2) {
                return -1;
            } else {
                return 0;
            }
        }
    }
    //用法
    arr.sort(compare("time"))

第二步:分割

//分割
    Array.prototype.chunk = function(size) {
        var array = this;
        const length = array.length 
        if (!length || !size || size < 1) {
            return []
        }
        
        let index = 0 
        let resIndex = 0 

        let result = new Array(Math.ceil(length / size))
        while (index < length) {
            result[resIndex++] = array.slice(index, (index += size))
        }
        return result
    }
    //用法
    arr.chunk(5)

第三步:抽离

    //抽离
    function sortArr(arr, str) {
        var _arr = [],
            _t = [],
            // 临时的变量
            _tmp;

        // 按照特定的参数将数组排序将具有相同值得排在一起
        arr = arr.sort(function(a, b) {
            var s = a[str],
                t = b[str];

            return s < t ? -1 : 1;
        });

        if ( arr.length ){
            // _tmp = arr[0][str];
            _tmp = new Date(arr[0][str]).getFullYear()
        }
        // 将相同类别的对象添加到统一个数组
        for (let i=0;i<arr.length;i++) {
            if(new Date(arr[i][str]).getFullYear()===_tmp){
                // if ( arr[i][str] === _tmp ){
                _t.push( arr[i] );
            } else {
                _tmp = new Date(arr[i][str]).getFullYear();
                _arr.push( _t );
                _t = [arr[i]];
            }
        }
        // 将最后的内容推出新数组
        _arr.push(_t);
        return _arr;
    }
    //用法,这里仅对一维数组使用
    sortArr( arr, 'time')
    //我将数据一二步处理后开始二叉数循环
    var cc = arr.sort(compare("time")).chunk(5)
    var _cc = []
    for(let i=0;i<cc.length;i++){
        //抽离
        var _datas=sortArr( cc[i], 'time')
        //根据所给数据结构进行赋值
        _cc.push({section:i+1, sectionDatas:[]})
        for(let o=0;o<_datas.length;o++){
            _cc[i].sectionDatas.push({
                data:new Date(_datas[o][0].time).getFullYear(),
                datas:[]
            })
        }
        for(let p=0;p<_cc[i].sectionDatas.length;p++){
            _cc[i].sectionDatas[p].datas=sortArr(cc[i], 'time')[p]
        }
    }

最近刚研究的函数式编程

功力不够,谨慎使用

    class Functor {
        constructor(data){
            this.data = data
        }

        map(data){
            return new Functor(data)
        }

        //排序
        compare(prop) {
            var result = this.data.sort(function (obj1, obj2) {
                var val1 = obj1[prop];
                var val2 = obj2[prop];
                if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
                    val1 = Number(val1);
                    val2 = Number(val2);
                }
                if (val1 < val2) {
                    return 1;
                } else if (val1 > val2) {
                    return -1;
                } else {
                    return 0;
                }
            })
            return this.map(result)
        }

        //分割
        chunk(size) {
            var array = this.data;
            //获取数组的长度,如果你传入的不是数组,那么获取到的就是undefined
            const length = array.length
            //判断不是数组,或者size没有设置,size小于1,就返回空数组
            if (!length || !size || size < 1) {
                return []
            }
            //核心部分
            let index = 0 //用来表示切割元素的范围start
            let resIndex = 0 //用来递增表示输出数组的下标

            //根据length和size算出输出数组的长度,并且创建它。
            let result = new Array(Math.ceil(length / size))
            //进行循环
            while (index < length) {
                //循环过程中设置result[0]和result[1]的值。该值根据array.slice切割得到。
                result[resIndex++] = array.slice(index, (index += size))
            }
            //输出新数组
            // return result
            return this.map(result)
        }

        //抽离
        sortArr(arr, str) {
            var _arr = [],
                _t = [],
                // 临时的变量
                _tmp;

            // 按照特定的参数将数组排序将具有相同值得排在一起
            arr = arr.sort(function(a, b) {
                var s = a[str],
                    t = b[str];

                return s < t ? -1 : 1;
            });

            if ( arr.length ){
                // _tmp = arr[0][str];
                _tmp = new Date(arr[0][str]).getFullYear()
            }
            // 将相同类别的对象添加到统一个数组
            for (let i=0;i<arr.length;i++) {
                if(new Date(arr[i][str]).getFullYear()===_tmp){
                    // if ( arr[i][str] === _tmp ){
                    _t.push( arr[i] );
                } else {
                    _tmp = new Date(arr[i][str]).getFullYear();
                    _arr.push( _t );
                    _t = [arr[i]];
                }
            }
            // 将最后的内容推出新数组
            _arr.push(_t);
            return _arr;
        }

        //转指定json格式
        dataToJSON(){
            var _json = []
            var _this = this;
            this.data.forEach(function(item,i){
                var _datas=_this.sortArr( item, 'time')
                _json.push({section:i+1, sectionDatas:[]})
                for(let o=0;o<_datas.length;o++){
                    _json[i].sectionDatas.push({
                        data:new Date(_datas[o][0].time).getFullYear(),
                        datas:[]
                    })
                }
                for(let p=0;p<_json[i].sectionDatas.length;p++){
                    _json[i].sectionDatas[p].datas=_datas[p]
                }
            })
            return _json
        }
    }
    Functor.of = function(data){
        return new Functor(data)
    }

使用方法

Functor.of(a).compare("time").chunk(5).dataToJSON()    //返回一个新的值,不改变原来数据
不交电费瞎发啥光 2022-09-14 15:55:08
var arr = new Object
data.forEach(function(d){
    var year = new Date(d.time).getFullYear()
    if(arr[year]){
        arr[year].push(d)
    }else{
        arr[year] = [d]
    }
})

提供个思路,修改一下应该能用

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文