Help to filter a JSON with jQuery?

Asked

Viewed 333 times

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 only the trecho[1].voo. My problem is that when it returns false or without any data it does not display the trecho[0].voo.

I’ll leave an example on Jsfiddle to better understand.

Example if the slide ranger 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 8:10 he returns nothing [] when it was to return like this:

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

In short: What I need to do and filter only the trecho[1] and maintain the trecho[0].

  • And why should he return trecho[0].voo if the filter is applied only in trecho[1].voo? By the way, it’s good you always refer to discussion that generated the code in question as it may be useful for those who will answer. For example, in this question you did not put what is the function horasParaMinutos. Incidentally, what is the difference between the questions exactly?

  • @Andersoncarloswoss this filter filters only the object trecho[1].voo. In the trecho[0].voo also has data but is not being filtered. The problem is that when the filter does not find any object that is within the hour selects it returns [] and does not return the data that is in trecho[0].voo. Or if there is no data in trecho[1].voo he does not display the trecho[0].voo. the horasParaMinutos and only to convert the hour to minute to be able to check if it is greater or less than the time received by the parameters horamin and horamax which is in minutes

  • Yes, because you are applying the filter to all elements based on the value of trecho[1]. If it has no value, it returns false for all positions in the list and it is null. You should only apply the filter using trecho[1] when item refer to section 1.

  • Dude, it got a little confused what you want... you want to filter only the stretch[1] and, if it didn’t work, show the stretch[0] or you want to filter all the passages and, if it didn’t work, show the stretch[0] ??

  • @J.Guilherme I want to filter only the stretch[1] and keep the stretch[0].

  • You want to filter the duration of the trip (hrDuracao), that’s it?

  • @Sergio I want to filter the hrDuracao only of trecho[1] and maintain the trecho[0].

  • Okay, so you’ll have a slider lasting (0 to type 24h) and then filter, right?

  • edited my answer, see if it works as expected

  • @Sergio yes. a slider from 0 to 24h and then filter only the stretch[1]. flight

Show 5 more comments

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 are longer than duracao. A working example would be 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>
<script src="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>

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 lightly 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);

  • Hi, how are you? I tried your code by swapping the first filter for foreach and put a console.log() in the result and is returning Undefined on the console. It’s like taking a look? http://jsfiddle.net/abjj8gkd/3/

0

To solve the problem of the stretch[0], just force the filter to return true when the 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, in all return objects the trecho[0] remains in the result.

  • I tried your code but I didn’t get the expected result. it shows me only the snippet[0] and not the snippet[1] together

  • It’s true... I edited the code to correct this behavior

Browser other questions tagged

You are not signed in. Login or sign up in order to post.