Help to filter a JSON with jQuery?

1

I have this code that filters a JSON object:

var filtrar =  function (horamin, horamax)
{
  var data = JSON.parse(JSON.stringify(json.aPesquisa));
  let result = data.filter(item => {
    let voos = item.trecho[1].voo.filter(voo => {
      var time = horasParaMinutos(voo.hrDuracao);
      console.log(horamin);
      return time >= horamin && time <= horamax;
    });
    item.trecho[1].voo = voos;
    return voos.length > 0;
  });
  return result;
};

This code filters out the trecho[1].voo . My problem is that when it returns false or with no data it does not display trecho[0].voo .

I'll leave you an example in the JSFiddle to better understand.

Example if the slider is selected the minimum time of 08:10 it returns this json:

[
    {
        "dsObservacao": null,
        "trecho": [
            {
                "sqTrecho": 1,
                "voo": [
                    {
                        "dtPartida": "20170720 11:20",
                        "dtChegada": "20170720 16:40",
                        "hrDuracao": "00:30"
                    }
                ]
            },
            {
                "sqTrecho": 2,
                "voo": [
                    {
                        "dtPartida": "20170727 14:15",
                        "dtChegada": "20170727 17:40",
                        "hrDuracao": "08:10"
                    }
                ]
            }
        ]
    }
]

If the time is greater than 08:10 it does not return anything [] when it was to return like this:

[
    {
        "dsObservacao": null,
        "trecho": [
            {
                "sqTrecho": 1,
                "voo": [
                    {
                        "dtPartida": "20170720 11:20",
                        "dtChegada": "20170720 16:40",
                        "hrDuracao": "00:30"
                    }
                ]
            }
        ]
    }
]

Summarizing : What do I need to do and filter only trecho[1] and keep trecho[0] .

    
asked by anonymous 07.07.2017 / 19:47

3 answers

5

What you need is:

var filtrados = json.aPesquisa.map(obj => {
    return obj.trecho.map(trecho => {
        return trecho.voo.filter(voo => {
            return horasParaMinutos(voo.hrDuracao) <= duracao
        });
    });
});

This filters flights that last longer than duracao . An example would look like this:

( jsFiddle )

var legenda = document.getElementById('legenda');
$("#slider").slider({
  animate: true,
  step: 1,
  min: 0,
  max: 1440, // 1440 são a quantidade de minutos num dia
  values: [0],
  slide: function(event, ui) {
    var val = ui.values[0];
    mostrarTrechos(json, val);
    legenda.innerHTML = [Math.floor(val / 60), val % 60].map(h => h < 10 ? '0' + h : h).join(':');
  }
});

function horasParaMinutos(str) {
  var horas = str.split(':').map(Number);
  return horas[0] * 60 + horas[1];
}

function mostrarTrechos(json, duracao) {
  var filtrados = json.aPesquisa.map(obj => {
    return obj.trecho.map(trecho => {
      return trecho.voo.filter(voo => {
        return horasParaMinutos(voo.hrDuracao) <= duracao
      });
    });
  });
  $('pre').text(JSON.stringify(filtrados, null, 2));
}

const json = {
  "aPesquisa": [{
      "dsObservacao": null,
      "trecho": [{
        "sqTrecho": 1,
        "voo": [{
          "dtPartida": "20170620 11:20",
          "dtChegada": "20170620 16:40",
          "hrDuracao": "01:20"
        }]
      }, {
        "sqTrecho": 2,
        "voo": [{

          "dtPartida": "20170627 04:10",
          "dtChegada": "20170627 07:40",
          "hrDuracao": "03:20"
        }, {
          "dtPartida": "20170627 14:15",
          "dtChegada": "20170627 17:40",
          "hrDuracao": "05:45"
        }]
      }]
    },

    {
      "dsObservacao": null,
      "trecho": [{
        "sqTrecho": 1,
        "voo": [{
          "dtPartida": "20170720 11:20",
          "dtChegada": "20170720 16:40",
          "hrDuracao": "00:30"
        }]
      }, {
        "sqTrecho": 2,
        "voo": [{

          "dtPartida": "20170727 04:10",
          "dtChegada": "20170727 07:40",
          "hrDuracao": "03:00"
        }, {
          "dtPartida": "20170727 14:15",
          "dtChegada": "20170727 17:40",
          "hrDuracao": "08:10"
        }]
      }]
    }
  ]
};
* {
  padding: 0;
  margin: 0;
}

#legenda {
  margin-top: 20px;
}

#sliderHolder {
  padding: 100px 20px 20px 20px;
}

.ui-slider {
  position: relative;
  height: 6px;
  background: #ddf;
  cursor: pointer;
  border-radius: 3px;
}

.ui-slider-range {
  position: absolute;
  height: 6px;
  background: #aaf;
  top: 0;
  font-size: 0;
}

.ui-slider-handle {
  position: absolute;
  height: 30px;
  top: -12px;
  width: 20px;
  margin-left: -10px;
  outline: none;
  background: #aab;
  border-radius: 5px;
}

.ui-slider-handle:hover,
.ui-slider-handle:active {
  background: #889;
}

.ui-disabled .ui-slider-range {
  background: grey;
}

.ui-disabled .ui-slider-handle {
  background: lightgrey;
}

.ui-disabled,
.ui-disabled .ui-slider-handle {
  cursor: default;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><scriptsrc="https://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<div id="sliderHolder">
  <div id="slider"></div>
  <div id="legenda"></div>
</div>
<pre></pre>
    
10.07.2017 / 21:42
4

Replace your first filter with a forEach.

var filtrar =  function (horamin, horamax)
{
  var data = JSON.parse(JSON.stringify(json.aPesquisa));
  let result = data.forEach(item => {
    let voos = item.trecho[1].voo.filter(voo => {
      var time = horasParaMinutos(voo.hrDuracao);
      return time >= horamin && time <= horamax;
    });
    item.trecho[1].voo = voos;
  });
  return result;
};

follows a slightly adapted example, so that it becomes complete.

let offset = new Date().getTimezoneOffset();
let Voo = function (partida, chegada) {
  this.partida = new Date(partida);
  this.chegada = new Date(chegada);
  this.partida.setMinutes(this.partida.getMinutes() - offset);
  this.chegada.setMinutes(this.chegada.getMinutes() - offset);
}

Object.defineProperty(Voo.prototype, "duracao", {
  get: function () {
    var date = new Date(this.chegada.getTime() - this.partida.getTime());
    date.setMinutes(date.getMinutes() + offset);
    return date;
  }
});

var getMinutes = function (voo) {
  var minutos = voo.duracao.getMinutes();
  var horas = voo.duracao.getHours();
  return horas * 60 + minutos;
}

var data = [
    {
        "dsObservacao": null,
        "trecho": [
            {
                "sqTrecho": 1,
                "voo": [
                    new Voo("2017-07-20T11:20", "2017-07-20T16:40")
                ]
            },
            {
                "sqTrecho": 2,
                "voo": [
                    new Voo("2017-07-27T14:15", "2017-07-27T17:40")
                ]
            }
        ]
    }
]

var filtrar =  function (data, horamin, horamax)
{
  data.forEach(item => {
    let voos = item.trecho[1].voo.filter(voo => {
      var time = getMinutes(voo);
      return time >= horamin && time <= horamax;
    });
    item.trecho.splice(1, 1);
  });
  return result;
};

var result = filtrar(data, 8 * 60 + 10, 20 * 60 + 20);
console.log(data);
    
10.07.2017 / 19:46
0

In order to solve the problem of the excerpt [0], only compel filter to return true when index is 0 . Something like this:

var filtrar =  function (horamin, horamax)
{
  var data = JSON.parse(JSON.stringify(json.aPesquisa));
  let result = data.filter((item,idx) => {
    if(idx === 0) return true;
    let voos = item.trecho[1].voo.filter(voo => {
      var time = horasParaMinutos(voo.hrDuracao);
      console.log(horamin);
      return time >= horamin && time <= horamax;
    });
    item.trecho[1].voo = voos;
    return voos.length > 0;
  });
  return result;
};

In this way, on all return objects, the trecho[0] is kept in the result.

    
10.07.2017 / 20:47