如何在不使用三个嵌套for循环的情况下解决这个问题

时间:2017-09-16 09:58:51

标签: javascript arrays object lodash

我有一个像这样的对象数组

var data = [{"2017-09-13":{date_time:"2017-09-13",value:"20"}},{"2017-09-13":{date_time:"2017-09-13",value:"22"}},{"2017-09-15":{date_time:"2017-09-15",value:"25"}},{"2017-09-15":{date_time:"2017-09-15",value:"30"}},{"2017-09-16":{date_time:"2017-09-16",value:"10"}}];

我有一系列像这样的日期

var dates = ["2017-09-13","2017-09-15"];

我想修改数据数组,使其只包含dates数组中提到的日期。我尝试过这样的事情

var date = [];
for (var i = 0; i < data.length; i++) {
        for (var j = 0; j < dates.length; j++) {
            for (key in data[i]) {
                if (dates[j] == key) {
                    date.push(data[i])
                }
            }
    }
}

它给了我所需的结果。然而,这不是有效的并且滞后于应用程序。有没有什么有效的方法呢?

编辑:更新了正确的数据结构

4 个答案:

答案 0 :(得分:2)

&#13;
&#13;
const data = [
    {
        "2017-09-13": {
            "date_time": "2017-09-13",
            "value": "20"
        }
    },
    {
        "2017-09-13": {
            "date_time": "2017-09-13",
            "value": "22"
        }
    },
    {
        "2017-09-15": {
            "date_time": "2017-09-15",
            "value": "25"
        }
    },
    {
        "2017-09-15": {
            "date_time": "2017-09-15",
            "value": "30"
        }
    },
    {
        "2017-09-16": {
            "date_time": "2017-09-16",
            "value": "10"
        }
    }
];

const dates = ["2017-09-13", "2017-09-15"];
const datesSet = new Set(dates);

const filteredData = data.filter(item => datesSet.has(Object.keys(item)[0]));
console.log(filteredData);
&#13;
&#13;
&#13;

考虑删除使用日期作为键,因为它们似乎是多余的信息:

&#13;
&#13;
const data = [
    {
        "date_time": "2017-09-13",
        "value": "20"
    },
    {
        "date_time": "2017-09-13",
        "value": "22"
    },
    {
        "date_time": "2017-09-15",
        "value": "25"
    },
    {
        "date_time": "2017-09-15",
        "value": "30"
    },
    {
        "date_time": "2017-09-16",
        "value": "10"
    }
];

const dates = ["2017-09-13", "2017-09-15"];
const datesSet = new Set(dates);

const filteredData = data.filter(item => datesSet.has(item.date_time));
console.log(filteredData);
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您的数据结构很难看。您将始终需要两个循环来迭代它。但是,我们可以设置更优雅的数据结构(也称为Map),我们可以更轻松地访问它:

 const days = new Map();

 for(const obj of data){
   for(day in obj){
    if( days.has(day) ){
      days.get(day).push( obj[day] );
    } else {
      days.set(day, [ obj[day] ]);
    }
  }
}

创建地图后,您只需执行以下操作:

days.get("2017-09-13")

获取具有日期时间/值的对象数组。这可以很容易地重复:

days.get("2017-09-13").forEach( ({value}) => {
  console.log(value);
});

或获得多个日期:

 const result = new Map(
   dates.map(date => [date, days.get( date )] )
 );

 console.log( [...result] );

仅限数据:

const result = [];
dates.forEach(date => result.push(...days.get(date)));

答案 2 :(得分:0)

这是一个只有两个for循环的解决方案。

&#13;
&#13;
var data = [{'2017-09-13':{date_time:"2017-09-13",value:"20"}},{'2017-09-13':{date_time:"2017-09-13",value:"22"}},{'2017-09-15':{date_time:"2017-09-15",value:"25"}},{'2017-09-15':{date_time:"2017-09-15",value:"30"}},{'2017-09-16':{date_time:"2017-09-16",value:"10"}}];

var date = [];
for (var i = 0; i < data.length; i++) {
      for (key in data[i]) {
          if (date.indexOf(key) === -1)  {
             date.push(key);
          }
      }
}

console.log(date);
&#13;
&#13;
&#13;

答案 3 :(得分:0)

var3

将数据转换为

var dataByDate = { };
for (var i = 0; i < data.length; i++) {
    for (var j in data[i])
        dataByDate[j] = dataByDate[j] || true;
}

然后你可以做

{ '2017-09-13': true, '2017-09-15': true, '2017-09-16': true }