Javascript 如何按关键字上的groupBy筛选对象数组?

Javascript 如何按关键字上的groupBy筛选对象数组?,javascript,arrays,ecmascript-6,javascript-objects,Javascript,Arrays,Ecmascript 6,Javascript Objects,我有下面的算法基础问题,我正试图用ES6解决它,但我被groupBy弄糊涂了 let data = [ {id: "2", time: "3/11/2016 02:02:58", value: 7.0}, {id: "1", time: "3/11/2016 02:12:32", value: 6.5}, {id: "1", time: "3/11/2016 02:13:11", value: 7.25}, {id: "4", time: "3/11/2016 02:13:54"

我有下面的算法基础问题,我正试图用ES6解决它,但我被
groupBy
弄糊涂了

let data = [
  {id: "2", time: "3/11/2016 02:02:58", value: 7.0},
  {id: "1", time: "3/11/2016 02:12:32", value: 6.5},
  {id: "1", time: "3/11/2016 02:13:11", value: 7.25},
  {id: "4", time: "3/11/2016 02:13:54", value: 8.75},
  {id: "2", time: "3/11/2016 05:02:45", value: 11.0},
  {id: "4", time: "3/11/2016 06:32:42", value: 5.0},
  {id: "2", time: "3/11/2016 06:35:12", value: 2.0},
  {id: "1", time: "3/11/2016 06:45:01", value: 12.0},
  {id: "1", time: "3/11/2016 06:59:59", value: 11.75},
  {id: "2", time: "3/11/2016 07:01:53", value: 1.0},
  {id: "1", time: "3/11/2016 07:02:54", value: 4.5},
  {id: "3", time: "3/11/2016 07:02:54", value: 15.75},
  {id: "6", time: "3/11/2016 07:02:54", value: 14.25},
  {id: "2", time: "3/11/2016 07:03:15", value: 12.0},
  {id: "2", time: "3/11/2016 08:02:22", value: 3.0},
  {id: "2", time: "3/11/2016 09:41:50", value: 4.0},
  {id: "2", time: "3/11/2016 10:02:54", value: 5.0},
  {id: "2", time: "3/11/2016 11:05:35", value: 10.0},
  {id: "2", time: "3/11/2016 13:02:21", value: 6.0},
  {id: "5", time: "3/11/2016 13:02:40", value: 8.0},
  {id: "4", time: "3/11/2016 13:02:55", value: 8.0},
  {id: "5", time: "3/11/2016 13:33:34", value: 8.0},
  {id: "5", time: "3/11/2016 13:42:24", value: 8.0},
  {id: "5", time: "3/11/2016 13:47:44", value: 6.25},
  {id: "5", time: "3/11/2016 14:02:54", value: 4.25},
  {id: "5", time: "3/11/2016 14:03:04", value: 5.25},
  {id: "5", time: "3/11/2016 15:12:55", value: 6.25},
  {id: "2", time: "3/11/2016 16:02:36", value: 8.0},
  {id: "5", time: "3/11/2016 16:22:11", value: 8.5},
  {id: "5", time: "3/11/2016 17:18:19", value: 11.25},
  {id: "5", time: "3/11/2016 18:19:20", value: 9.0},
  {id: "2", time: "3/11/2016 23:59:59", value: 9.0}
];
正在尝试获取具有以下条件的数组子集:

  • 每个
    id
    在每个一小时内,结果集中只应包含最昂贵的值
  • 如果一个小时内具有相同
    id
    的多个对象等于最昂贵的值,则只放置最早的一个
  • 如果一个
    id
    的对象在整个对象数组中超过8个,请将其删除 我知道在SQL中,MAX在'value'和GroupBy在'time'列上很容易实现,但这里我对JS循环感到困惑。如果可能的话,请建议一些技巧

    我试着像下面那样,但似乎还有很长的路要走

    var newArr = [];
    data.forEach(function (el) {
        var findIndex = newArr.findIndex(function (item) {
            return item.time === el.time;
        });
        if (findIndex === -1) {
            newArr.push(el);
        } else if (el.value > newArr[findIndex].value) {
            newArr[findIndex].value = el.value;
            newArr[findIndex].time = el.time;
        } else {
            newArr[findIndex].time = el.time;
        }
    });
    
    只是为了让它更清楚,输出将是这样的

    [
      { id: "4",time: "3/11/2016 02:13:54",value: 8.75 },
      { id: "1", time: "3/11/2016 06:45:01",value: 12.0 },
      { id: "3",time: "3/11/2016 07:02:54",value: 15.75 },
      { id: "4", time: "3/11/2016 13:02:55", value: 8.0}
    ]
    
    id记录:“2”和“5”已删除,因为它具有8个以上的外观 我发现了一些东西,但似乎是ruby

    你需要
    a) 从数据['time']创建日期对象
    b) 使用对象以某种方式对数组进行排序。
    c) 过滤掉过多的数据

    希望代码能够自我解释。我试着用一种动态的方式来做这件事,所以你可以用它来做各种各样的年、月、日,因为我想这不仅仅是你想要的时间

    filterOutOldestIds
    有一个非常难看的嵌套for循环,但如果我希望它是动态的,但仍然可以管理,我想不出更好的方法

    let数据=[
    {id:“2”,时间:“3/11/2016 02:02:58”,值:7.0},
    {id:“1”,时间:“3/11/2016 02:12:32”,值:6.5},
    {id:“1”,时间:“3/11/2016 02:13:11”,值:7.25},
    {id:“4”,时间:“3/11/2016 02:13:54”,值:8.75},
    {id:“2”,时间:“3/11/2016 05:02:45”,值:11.0},
    {id:“4”,时间:“3/11/2016 06:32:42”,值:5.0},
    {id:“2”,时间:“3/11/2016 06:35:12”,值:2.0},
    {id:“1”,时间:“3/11/2016 06:45:01”,值:12.0},
    {id:“1”,时间:“3/11/2016 06:59:59”,值:11.75},
    {id:“2”,时间:“3/11/2016 07:01:53”,值:1.0},
    {id:“1”,时间:“3/11/2016 07:02:54”,值:4.5},
    {id:“3”,时间:“3/11/2016 07:02:54”,值:15.75},
    {id:“6”,时间:“3/11/2016 07:02:54”,值:14.25},
    {id:“2”,时间:“3/11/2016 07:03:15”,值:12.0},
    {id:“2”,时间:“3/11/2016 08:02:22”,值:3.0},
    {id:“2”,时间:“3/11/2016 09:41:50”,值:4.0},
    {id:“2”,时间:“3/11/2016 10:02:54”,值:5.0},
    {id:“2”,时间:“3/11/2016 11:05:35”,值:10.0},
    {id:“2”,时间:“3/11/2016 13:02:21”,值:6.0},
    {id:“5”,时间:“3/11/2016 13:02:40”,值:8.0},
    {id:“4”,时间:“3/11/2016 13:02:55”,值:8.0},
    {id:“5”,时间:“3/11/2016 13:33:34”,值:8.0},
    {id:“5”,时间:“3/11/2016 13:42:24”,值:8.0},
    {id:“5”,时间:“3/11/2016 13:47:44”,数值:6.25},
    {id:“5”,时间:“3/11/2016 14:02:54”,值:4.25},
    {id:“5”,时间:“3/11/2016 14:03:04”,值:5.25},
    {id:“5”,时间:“3/11/2016 15:12:55”,值:6.25},
    {id:“2”,时间:“3/11/2016 16:02:36”,值:8.0},
    {id:“5”,时间:“3/11/2016 16:22:11”,值:8.5},
    {id:“5”,时间:“3/11/2016 17:18:19”,值:11.25},
    {id:“5”,时间:“3/11/2016 18:19:20”,数值:9.0},
    {id:“2”,时间:“3/11/2016 23:59:59”,值:9.0}
    ];
    函数过滤器最大值(arr){
    设最大发生次数=8;
    var controlObj={},
    SorterDar=[];//实际上并不需要这个,但使用它可以增加清晰度
    arr.forEach((el)=>{
    controlObj=setHighestValueBasedOnDate(el,controlObj);
    });
    分拣机=过滤器自动分拣(控制对象,最大发生次数);
    返回分拣机;
    }
    函数setHighestValueBasedOnDate(el,controlObj){
    let date=新日期(el.时间),
    年份=日期。getFullYear(),
    月=日期。getMonth(),
    day=date.getDay(),
    小时=日期。getHours(),
    id=el.id;
    controlObj=createDefaultStructure(id、年、月、日、小时、controlObj);
    设previousEl=controlObj[id][year][month][day][hour];
    controlObj[id][year][month][day][hour]=(上一个el和上一个el.value>el.value)?上一个el:el;
    返回控制对象;
    }
    函数createDefaultStructure(id、年、月、日、小时、controlObj){
    controlObj[id]=controlObj[id]| |{};
    controlObj[id][year]=controlObj[id][year]| |{};
    controlObj[id][year][month]=controlObj[id][year][month]|{};
    controlObj[id][year][month][day]=controlObj[id][year][month][day]|{};
    返回控制对象;
    }
    函数过滤器自动测试(controlObj,maxAllowedOccurances){
    变量排序器=[],
    i发生率={},
    idObj、yearObj、monthObj、dayObj、hourObj;
    for(controlObj中的id){
    i发生率[id]=-1;
    idObj=controlObj[id];
    用于(idObj年){
    yearObj=idObj[year];
    年(月)OBJ{
    dayObj=年对象【月】;
    用于(以dayObj为单位的小时){
    hourObj=dayObj[小时];
    用于(霍罗布岛的el){
    i发生率[id]++;
    //除了“controlObj中的id”之外,该检查应该在每个for循环中进行
    如果(i发生率[id]<最大允许发生率){
    分拣机推送(hourObj[el]);
    }否则{
    打破
    }
    }
    }
    }
    }
    }
    返回分拣机;
    }
    设sortedData=filterOnMaxValue(数据);
    控制台日志(sortedData)
    
    尝试获取具有以下条件的数组子集

    • 在每个一小时内的每个Id中,resultset中只应包含最昂贵的值
    • 如果来自同一Id的多个对象在一小时内等于最昂贵的值,则只放置最早的一个
    • 如果在整个对象数组中一个Id有8个以上的对象,请将其删除

    @Spangle看看我编辑的问题。。希望你能理解我的意图,在你的代码片段中,你想检查是否有超过8个对象