鍍金池/ 問(wèn)答/人工智能  HTML/ 怎么對(duì)一組數(shù)據(jù)按照某個(gè)特定字段進(jìn)行分組?

怎么對(duì)一組數(shù)據(jù)按照某個(gè)特定字段進(jìn)行分組?

比如我有一組數(shù)據(jù)

[
  {
    '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,
  }    
]

實(shí)際業(yè)務(wù)場(chǎng)景是對(duì)這組數(shù)據(jù)進(jìn)行分組,每5條一組 但是這5條還要根據(jù)他們的日期年份分小組

比如上面這7條分出來(lái)結(jié)果就是:

[
  {
    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,
          } 
        ]
      }
    ]
  } 
]

這個(gè)算法該怎么寫(xiě)呢。。求指教

回答
編輯回答
初念

步驟

*第一步:排序,時(shí)間從近到遠(yuǎn)
*第二步:分割,將數(shù)組分成5個(gè)一組,返回新數(shù)組
*第三步:抽離,將相同時(shí)間抽離出來(lái)組成要求上的數(shù)據(jù)格式

代碼

第一步:排序
    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 = [],
            // 臨時(shí)的變量
            _tmp;

        // 按照特定的參數(shù)將數(shù)組排序?qū)⒕哂邢嗤档门旁谝黄?        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()
        }
        // 將相同類(lèi)別的對(duì)象添加到統(tǒng)一個(gè)數(shù)組
        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]];
            }
        }
        // 將最后的內(nèi)容推出新數(shù)組
        _arr.push(_t);
        return _arr;
    }
    //用法,這里僅對(duì)一維數(shù)組使用
    sortArr( arr, 'time')
    //我將數(shù)據(jù)一二步處理后開(kāi)始二叉數(shù)循環(huán)
    var cc = arr.sort(compare("time")).chunk(5)
    var _cc = []
    for(let i=0;i<cc.length;i++){
        //抽離
        var _datas=sortArr( cc[i], 'time')
        //根據(jù)所給數(shù)據(jù)結(jié)構(gòu)進(jìn)行賦值
        _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]
        }
    }

最近剛研究的函數(shù)式編程

功力不夠,謹(jǐn)慎使用
    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;
            //獲取數(shù)組的長(zhǎng)度,如果你傳入的不是數(shù)組,那么獲取到的就是undefined
            const length = array.length
            //判斷不是數(shù)組,或者size沒(méi)有設(shè)置,size小于1,就返回空數(shù)組
            if (!length || !size || size < 1) {
                return []
            }
            //核心部分
            let index = 0 //用來(lái)表示切割元素的范圍start
            let resIndex = 0 //用來(lái)遞增表示輸出數(shù)組的下標(biāo)

            //根據(jù)length和size算出輸出數(shù)組的長(zhǎng)度,并且創(chuàng)建它。
            let result = new Array(Math.ceil(length / size))
            //進(jìn)行循環(huán)
            while (index < length) {
                //循環(huán)過(guò)程中設(shè)置result[0]和result[1]的值。該值根據(jù)array.slice切割得到。
                result[resIndex++] = array.slice(index, (index += size))
            }
            //輸出新數(shù)組
            // return result
            return this.map(result)
        }

        //抽離
        sortArr(arr, str) {
            var _arr = [],
                _t = [],
                // 臨時(shí)的變量
                _tmp;

            // 按照特定的參數(shù)將數(shù)組排序?qū)⒕哂邢嗤档门旁谝黄?            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()
            }
            // 將相同類(lèi)別的對(duì)象添加到統(tǒng)一個(gè)數(shù)組
            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]];
                }
            }
            // 將最后的內(nèi)容推出新數(shù)組
            _arr.push(_t);
            return _arr;
        }

        //轉(zhuǎn)指定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()    //返回一個(gè)新的值,不改變?cè)瓉?lái)數(shù)據(jù)
2018年4月15日 08:25
編輯回答
雨萌萌
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]
    }
})

提供個(gè)思路,修改一下應(yīng)該能用

2018年8月21日 10:35