Lodash - 过滤嵌套数组,传递一个函数

时间:2017-09-30 01:08:04

标签: javascript angularjs arrays nested lodash

我找不到一种方法来过滤和提取与特定条件/表达式匹配的嵌套数组中的itens

我已经检查了下面这些链接,但提供的解决方案不会将函数传递给_.filter:

Find object by match property in nested array

lodash property search in array and in nested child arrays

Lodash - Search Nested Array and Return Object

所以,让我更好地解释一下。我目前的数据看起来像这样: 如何检索匹配条件的所有对象的“listEvents”数组中的itens?

[
  {
    "ModalidadeId": 1,
    "Nome": "SOCCER",
    "Ordem": "09",
    "IconeId": "",
    "listEvents": [
      {
        "EI": 2960542,
        "No": "SÃO PAULO SP X ATLÉTICO LINENSE-SP",
        "St": 1,
        "Ini": "2017-09-30T10:00:00",
        "MI": 1,
        "CI": 251,
        "TI": 4993,
        "StAV": 0,
        "De": false,
        "Ics": [
          "p22678",
          "p22684"
        ],
        "Ic": "",
        "Tas": [],
        "show": true,
        "IniFormatada": "30/09/2017 às 10:00:00",
        "MN": "FUTEBOL"
      },
      {
        "EI": 3260915,
        "No": "SÃO PAULO SP X ATLÉTICO LINENSE-SP",
        "St": 0,
        "Ini": "2017-09-30T10:00:00",
        "MI": 1,
        "CI": 251,
        "TI": 4993,
        "StAV": 0,
        "De": false,
        "Ics": [
          "p29076",
          "p22684"
        ],
        "Ic": "",
        "Tas": [],
        "show": true,
        "IniFormatada": "30/09/2017 às 10:00:00",
        "MN": "FUTEBOL"
      },
      {
        "EI": 430219,
        "No": "NOROESTE SP X GREMIO NOVORIZONTINO SP",
        "St": 0,
        "Ini": "2017-09-30T15:00:00",
        "MI": 1,
        "CI": 251,
        "TI": 2580,
        "StAV": 0,
        "De": false,
        "Ics": [
          "p31209",
          "p31113"
        ],
        "Ic": "",
        "Tas": [],
        "show": true,
        "IniFormatada": "30/09/2017 às 15:00:00",
        "MN": "FUTEBOL"
      },
      {
        "EI": 443844,
        "No": "COMERCIAL FC SP X BATATAIS FUTEBOL CLUBE SP",
        "St": 0,
        "Ini": "2017-09-30T15:00:00",
        "MI": 1,
        "CI": 251,
        "TI": 2580,
        "StAV": 0,
        "De": false,
        "Ics": [
          "p31200",
          "p31212"
        ],
        "Ic": "",
        "Tas": [],
        "show": true,
        "IniFormatada": "30/09/2017 às 15:00:00",
        "MN": "FUTEBOL"
      }
    ]
  },
  {
    "ModalidadeId": 2,
    "Nome": "TENIS",
    "Ordem": "09",
    "IconeId": "",
    "listEvents": [
      {
        "EI": 2960542,
        "No": "SÃO PAULO SP X ATLÉTICO LINENSE-SP",
        "St": 1,
        "Ini": "2017-09-30T10:00:00",
        "MI": 1,
        "CI": 251,
        "TI": 4993,
        "StAV": 0,
        "De": false,
        "Ics": [
          "p22678",
          "p22684"
        ],
        "Ic": "",
        "Tas": [],
        "show": true,
        "IniFormatada": "30/09/2017 às 10:00:00",
        "MN": "FUTEBOL"
      },
      {
        "EI": 3260915,
        "No": "SÃO PAULO SP X ATLÉTICO LINENSE-SP",
        "St": 0,
        "Ini": "2017-09-30T10:00:00",
        "MI": 1,
        "CI": 251,
        "TI": 4993,
        "StAV": 0,
        "De": false,
        "Ics": [
          "p29076",
          "p22684"
        ],
        "Ic": "",
        "Tas": [],
        "show": true,
        "IniFormatada": "30/09/2017 às 10:00:00",
        "MN": "FUTEBOL"
      },
      {
        "EI": 430219,
        "No": "NOROESTE SP X GREMIO NOVORIZONTINO SP",
        "St": 0,
        "Ini": "2017-09-30T15:00:00",
        "MI": 1,
        "CI": 251,
        "TI": 2580,
        "StAV": 0,
        "De": false,
        "Ics": [
          "p31209",
          "p31113"
        ],
        "Ic": "",
        "Tas": [],
        "show": true,
        "IniFormatada": "30/09/2017 às 15:00:00",
        "MN": "FUTEBOL"
      },
      {
        "EI": 443844,
        "No": "COMERCIAL FC SP X BATATAIS FUTEBOL CLUBE SP",
        "St": 0,
        "Ini": "2017-09-30T15:00:00",
        "MI": 1,
        "CI": 251,
        "TI": 2580,
        "StAV": 0,
        "De": false,
        "Ics": [
          "p31200",
          "p31212"
        ],
        "Ic": "",
        "Tas": [],
        "show": true,
        "IniFormatada": "30/09/2017 às 15:00:00",
        "MN": "FUTEBOL"
      }
    ]
  }
]

这是我到目前为止尝试过的代码,但它似乎没有用。

_.filter($scope.listModalities, _.flow(
            _.property('listEvents'),
            _.partialRight(_.filter, function (o) {
              var eventDate = new Date(o.Ini);
              eventDate.setHours(eventDate.getHours() - 24);
              var now = new Date();
              return o.De == true || eventDate < now;
            })
          ));

2 个答案:

答案 0 :(得分:1)

如果您maplistEvents然后flatten,您可以摆脱一个迭代循环并获得您想要的结果:

var now = new Date();
var listEvents = _.chain(input).map((o) => o.listEvents).flatten().filter((o)=> {
  if(o.De === true) return true;
  var eventDate = new Date(o.Ini);
  eventDate.setHours(eventDate.getHours() - 24);
  return eventDate < now;
}).value();

now = null;

另外,您会注意到我移动了等式检查o.De === true,这样如果它是true,函数将返回而无需额外的计算。此外,为了提高效率,我将now的定义移出了迭代。

此处还有pen

此外,这里是es5中的样子。

var now = new Date();
var listEvents = _.chain(input).map(function (o) {
  return o.listEvents;
}).flatten().filter(function (o) {
  if (o.De === true) return true;
  var eventDate = new Date(o.Ini);
  eventDate.setHours(eventDate.getHours() - 24);
  return eventDate < now;
}).value();

pen一起去。

此外,正如评论中所建议的那样,您可以使用flatMap保存另一个步骤:

var now = new Date();
var listEvents = _.chain(input).flatMap('listEvents').filter(function (o) {
  if (o.De === true) return true;
  var eventDate = new Date(o.Ini);
  eventDate.setHours(eventDate.getHours() - 24);
  return eventDate < now;
}).value();

console.log(listEvents);

pen

答案 1 :(得分:1)

也许你可以尝试使用vanilla javascript方式

var listEvents = []

myData.forEach((item) => {
item.listEvents.forEach((event) => {
     var eventDate = new Date(event.Ini);
     eventDate.setHours(eventDate.getHours() - 24);
     var now = new Date();
     if(event.De == true || eventDate < now){
        listEvents.push(event);
     }
  })
})