Help with Json filter with jQuery

1

I need help with the filter in Json with jQuery, I have this code:

var chamaFiltro = function(horaminida){
  var pesquisa = {
    idamin: horasParaMinutos(horaminida)
  };

  var filtrados = json.aPesquisa.filter(function(voo) {
    voo = JSON.parse(JSON.stringify(voo));
    voo.trecho = voo.trecho.filter(function(trecho){
      trecho = JSON.parse(JSON.stringify(trecho));
      trecho.voo = trecho.voo.filter(function(voos){
        return horasParaMinutos(voos.dtPartida.slice(9, 14)) >= pesquisa.idamin;
      });
      return trecho.voo.length > 0;
    });
    return voo.trecho.length > 0;
  });
  console.log(filtrados);
};

It filters a JSON and returns me the time is greater than the selected time in a slide range .

If you put one:

  

console.log (excerpt.voo);

Instead of:

  

return stretch.voo.length > 0;

It is noticed in the console that it normally filters but when I try to give a return it returns all the data until those that are smaller than the time of slide range .

Does anyone know how I can return only the filtered data?

When calling the function, does it only return the filtered data?

  

Flame (Horaminida);

Json:

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

                     "dtPartida":"20170627 04:10",
                     "dtChegada":"20170627 07:40"
                  },
                  {
                     "dtPartida":"20170627 14:15",
                     "dtChegada":"20170627 17:40"
                  }
               ]
            }
         ]
      },

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

                     "dtPartida":"20170727 04:10",
                     "dtChegada":"20170727 07:40"
                  },
                  {
                     "dtPartida":"20170727 14:15",
                     "dtChegada":"20170727 17:40"
                  }
               ]
            }
         ]
      }
   ]
}
Assuming I select 10:30 in the slide range it should return me only where the dtPartida(dtPartida.slcie(9, 14)) time is greater than the selected time in slide range in case 10:30. the return would look like this:

[
  {
     "dsObservacao":null,
     "trecho":[
        {
           "sqTrecho":1,
           "voo":[
              {
                "dtPartida":"20170620 11:20",
                "dtChegada":"20170620 16:40"
              }
           ]
        },
        {
           "sqTrecho":2,
           "voo":[
              {
                 "dtPartida":"20170627 14:15",
                 "dtChegada":"20170627 17:40"
              }
           ]
        }
     ]
  },

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

Follow the code on JSFiddle

    
asked by anonymous 19.06.2017 / 20:34

3 answers

4

Consider the following data:

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

                     "dtPartida":"20170627 04:10",
                     "dtChegada":"20170627 07:40"
                  },
                  {
                     "dtPartida":"20170627 14:15",
                     "dtChegada":"20170627 17:40"
                  }
               ]
            }
         ]
      },

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

                     "dtPartida":"20170727 04:10",
                     "dtChegada":"20170727 07:40"
                  },
                  {
                     "dtPartida":"20170727 14:15",
                     "dtChegada":"20170727 17:40"
                  }
               ]
            }
         ]
      }
   ]
};

The idea is to define a function that, for an entry time, returns all items in the list that have dtPartida greater than or equal to this time. One solution, using ES6, is to copy the data and filter them through filter :

function chamaFiltro (horaminida)
{
  // Copia os dados para 'data':
  let data = JSON.parse(JSON.stringify(json))

  // Filtra os dados em 'aPesquisa':
  let result = data.aPesquisa.filter(item => {

    /// ...

  });

  // Retorna o resultado:
  return result;
}

But each item in aPesquisa can have multiple values in trecho , so we should filter the data in trecho also:

function chamaFiltro (horaminida)
{
  // Copia os dados para 'data':
  let data = JSON.parse(JSON.stringify(json))

  // Filtra os dados em 'aPesquisa':
  let result = data.aPesquisa.filter(item => {

    // Filtra os dados em 'aPesquisa[i].trecho':
    let trechos = item.trecho.filter(trecho => {

      // ...

    });

    // Atualiza os valores filtrados dos trechos:
    item.trecho = trechos;

    // Mantém no resultado final se possuir dados em trecho:
    return trechos.length > 0;

  });

  // Retorna o resultado:
  return result;
}

But each snippet can have multiple values in voo , so we must filter the data in voo also:

function chamaFiltro (horaminida)
{
  // Copia os dados para 'data':
  let data = JSON.parse(JSON.stringify(json))

  // Filtra os dados em 'aPesquisa':
  let result = data.aPesquisa.filter(item => {

    // Filtra os dados em 'aPesquisa[i].trecho':
    let trechos = item.trecho.filter(trecho => {

      let voos = trecho.voo.filter(voo => {

        // ...

      });

      // Atualiza os valores filtrados dos voos:
      trecho.voo = voos;

      // Mantém no resultado final se possuir dados em voo:
      return voos.length > 0;

    });

    // Atualiza os valores filtrados dos trechos:
    item.trecho = trechos;

    // Mantém no resultado final se possuir dados em trecho:
    return trechos.length > 0;

  });

  // Retorna o resultado:
  return result;
}

Finally we can filter the data of voo based on the value of dtPartida . For this, we need to check if the time of the same is greater than or equal to that defined by horaminida .

function chamaFiltro (horaminida)
{
  // Copia os dados para 'data':
  let data = JSON.parse(JSON.stringify(json))

  // Filtra os dados em 'aPesquisa':
  let result = data.aPesquisa.filter(item => {

    // Filtra os dados em 'aPesquisa[i].trecho':
    let trechos = item.trecho.filter(trecho => {

      let voos = trecho.voo.filter(voo => {

        // Extrai o horário de 'dtPartida':
        let time = voo.dtPartida.split(' ')[1];

        // Mantém no resultado final se o horário for maior ou igual ao de entrada:
        return time > horaminida;

      });

      // Atualiza os valores filtrados dos voos:
      trecho.voo = voos;

      // Mantém no resultado final se possuir dados em voo:
      return voos.length > 0;

    });

    // Atualiza os valores filtrados dos trechos:
    item.trecho = trechos;

    // Mantém no resultado final se possuir dados em trecho:
    return trechos.length > 0;

  });

  // Retorna o resultado:
  return result;
}

In this way, if we call the function chamaFiltro("10:30") , the output will be:

[
  [object Object] {
    dsObservacao: null,
    trecho: [[object Object] {
      sqTrecho: 1,
      voo: [[object Object] {
        dtChegada: "20170620 16:40",
        dtPartida: "20170620 11:20"
      }]
    }, [object Object] {
      sqTrecho: 2,
      voo: [[object Object] {
        dtChegada: "20170627 17:40",
        dtPartida: "20170627 14:15"
      }]
    }]
  }, [object Object] {
    dsObservacao: null,
    trecho: [[object Object] {
      sqTrecho: 1,
      voo: [[object Object] {
        dtChegada: "20170720 16:40",
        dtPartida: "20170720 11:20"
      }]
    }, [object Object] {
      sqTrecho: 2,
      voo: [[object Object] {
        dtChegada: "20170727 17:40",
        dtPartida: "20170727 14:15"
      }]
    }]
  }
]

Possessing only the desired values.

  

See working in JSBin or Repl.it .

Only after I've decided that I can understand what you've done, I realize that it's exactly the same logic. The only difference is that you clone the voo and trecho objects inside the filters and this is the error. The callback function of the filter returns a Boolean value that, if true, holds the original object in the list. That is, you clone the object, but when it returns true in the filter, instead of keeping in the list the clone, which would be modified by internal filters, keeps the original object with all the times. To get around this, just clone the entire object before filtering it and just modify it in the internal filters, as I did above. See that I cloned the object using Object.assign , but it's possible to do with JSON, just like you did.

    
23.06.2017 / 19:29
3
function filtroHora(horaminida, horamaxida, horaminvolta, horamaxvolta){
   var trechos = jsonParaFiltrar.aPesquisa;
   var trechosFiltrados = trechos.filter(function(trecho){
       //essa função retorna para um vetor apenas os itens que retornarem true
       var estaNoRange = suaLogicaAqui;
       return estaNoRange;
   }
}
    
19.06.2017 / 20:53
1

Here's one more suggestion:

jsFiddle: link

The central part would be:

function filtrar(json, min, max) {
    return json.aPesquisa.map(obj => {
        return obj.trecho.filter(trecho => {
            var partida = horasParaMinutos(trecho.voo[0].dtPartida);
            var chegada = horasParaMinutos(trecho.voo[0].dtChegada);
            return partida >= min && chegada <= max;
        });
    });
}

which filters the arrays according to the minimum and maximum.

A working example would be:

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

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

function filtrar(json, min, max) {
    return json.aPesquisa.map(obj => {
        return obj.trecho.filter(trecho => {
            var partida = horasParaMinutos(trecho.voo[0].dtPartida);
            var chegada = horasParaMinutos(trecho.voo[0].dtChegada);
            return partida >= min && chegada <= max;
        });
    });
}

function mostrarTrechos(min, max) {
    var filtrados = filtrar(json, min || 0, max || 1440);
    $('pre').text(JSON.stringify(filtrados, null, 4));
}

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

                    "dtPartida": "20170627 04:10",
                    "dtChegada": "20170627 07:40"
                }, {
                    "dtPartida": "20170627 14:15",
                    "dtChegada": "20170627 17:40"
                }]
            }]
        },

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

                    "dtPartida": "20170727 04:10",
                    "dtChegada": "20170727 07:40"
                }, {
                    "dtPartida": "20170727 14:15",
                    "dtChegada": "20170727 17:40"
                }]
            }]
        }
    ]
};
* {
    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.9.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>
    
24.06.2017 / 18:52