Как фильтровать данные json по диапазону дат в javascript



Я хочу отфильтровать приведенные ниже данные json по дате начала и дате окончания, он должен вернуть данные между датой начала и датой окончания, я пытался достичь с помощью кода ниже, но я делаю что-то неправильно для фильтрации. Я новичок в интерфейсных технологиях, таких как Javascript и jquery, и был бы признателен, если бы кто-то мог исправить меня, что я делаю неправильно здесь:



<html>
<head>
<title>Test</title>

</head>

<body>

<script type="text/javascript">
var product_data = [
{
"productId": "12",
"productName": "ProductA",
"productPrice": "1562",
"ProductDateCreated": "2015-07-24T12:58:17.430Z",
"TotalProduct": 294
},
{
"productId": "13",
"productName": "ProductB",
"productPrice": "8545",
"TotalProduct": 294,
"ProductHits": {
"2015-08-01T00:00:00Z"
}
},
{
"productId": "14",
"productName": "ProductC",
"productPrice": "8654",
"TotalProduct": 78,
"ProductHits": {
"2015-08-10T00:00:00Z"
}
},
{
"productId": "15",
"productName": "ProductD",
"productPrice": "87456",
"TotalProduct": 878,
"ProductHits": {
"2015-05-12T00:00:00Z"
}
}
];

var startDate = "2015-08-04";
var endDate = "2015-08-12";

var resultProductData = product_data.filter(
function (a)
{
return (a.ProductHits) > startDate && (a.ProductHits) < endDate;
});
console.log(resultProductData);
</script>

</body>
</html>
517   2  

2 ответов:

        var startDate = new Date("2015-08-04");
        var endDate = new Date("2015-08-12");

        var resultProductData = product_data.filter(function (a) {
            var hitDates = a.ProductHits || {};
            // extract all date strings
            hitDates = Object.keys(hitDates);
            // convert strings to Date objcts
            hitDates = hitDates.map(function(date) { return new Date(date); });
            // filter this dates by startDate and endDate
            var hitDateMatches = hitDates.filter(function(date) { return date >= startDate && date <= endDate });
            // if there is more than 0 results keep it. if 0 then filter it away
            return hitDateMatches.length>0;
        });
        console.log(resultProductData);

Скрипка: http://jsfiddle.net/4nz1ahuw/


Обновление как предлагает Ates Goral в комментариях, решение выше может быть оптимизировано с помощью массива.образцы.некоторые:

        var startDate = new Date("2015-08-04");
        var endDate = new Date("2015-08-12");

        var resultProductData = product_data.filter(function (a) {
            var hitDates = a.ProductHits || {};
            // extract all date strings
            hitDates = Object.keys(hitDates);
            // improvement: use some. this is an improment because .map()
            // and .filter() are walking through all elements.
            // .some() stops this process if one item is found that returns true in the callback function and returns true for the whole expression
            hitDateMatchExists = hitDates.some(function(dateStr) {
                var date = new Date(dateStr);
                return date >= startDate && date <= endDate
            });
            return hitDateMatchExists;
        });
        console.log(resultProductData);

Спасибо за хороший совет :)

Для вас значения дат должны быть инкапсулированы как таковые, например. новая дата (ваше значение даты)

Другой подход дается с использованием следующего примера в качестве руководства:

Https://jsfiddle.net/ladiv7/tb66ya67/

/*Dummy Data, Courtesy of: https://www.generatedata.com/*/
var dataDates = [{
    "date": "Nov 28, 2017",
    "name": "Samuel A. Kidd",
    "email": "[email protected]",
    "address": "944-343 Nec Avenue"
  },
  {
    "date": "May 20, 2015",
    "name": "Jenna R. Alston",
    "email": "[email protected]",
    "address": "5316 Mollis Av."
  },
  {
    "date": "Mar 11, 2018",
    "name": "Magee K. Mcfarland",
    "email": "[email protected]",
    "address": "Ap #605-1298 Id Rd."
  },
  {
    "date": "Dec 9, 2016",
    "name": "Claudia V. Campbell",
    "email": "[email protected]",
    "address": "Ap #935-7909 Lectus Rd."
  },
  {
    "date": "Aug 4, 2015",
    "name": "Steven V. Reynolds",
    "email": "[email protected]",
    "address": "Ap #501-8119 Vel, Rd."
  },
  {
    "date": "Mar 25, 2019",
    "name": "Amy O. Bean",
    "email": "[email protected]",
    "address": "1855 Euismod Ave"
  },
  {
    "date": "Jan 12, 2019",
    "name": "Quintessa H. Clay",
    "email": "[email protected]",
    "address": "P.O. Box 127, 812 Lobortis Rd."
  },
  {
    "date": "Feb 7, 2015",
    "name": "Marvin P. Golden",
    "email": "[email protected]",
    "address": "P.O. Box 936, 8921 Augue Av."
  },
  {
    "date": "Aug 4, 2015",
    "name": "Shay Z. Clayton",
    "email": "[email protected]",
    "address": "5862 Pede St."
  },
  {
    "date": "Feb 12, 2015",
    "name": "Jin G. Jimenez",
    "email": "[email protected]",
    "address": "4310 Malesuada Av."
  },
  {
    "date": "Feb 10, 2017",
    "name": "Dawn R. Blackwell",
    "email": "[email protected]",
    "address": "5585 Metus. St."
  },
  {
    "date": "Apr 28, 2015",
    "name": "Audra A. Gates",
    "email": "[email protected]",
    "address": "448-332 Iaculis Ave"
  },
  {
    "date": "May 6, 2018",
    "name": "Gloria K. Dodson",
    "email": "[email protected]",
    "address": "564-3879 Vel, St."
  },
  {
    "date": "Jan 1, 2015",
    "name": "Inga I. Vinson",
    "email": "[email protected]",
    "address": "320-4632 Lacus. Road"
  },
  {
    "date": "Jul 21, 2015",
    "name": "Berk M. Owen",
    "email": "[email protected]",
    "address": "727 Bibendum Ave"
  },
  {
    "date": "Feb 27, 2016",
    "name": "Jessica C. Thompson",
    "email": "[email protected]",
    "address": "P.O. Box 903, 2394 A, St."
  }
];



$(document).ready(function() {

  $('.datepicker').datepicker(); //Activates the datepicker Materialize CSS element

  preview_json(dataDates, $("#view_rawData")); //show the original data on the screen
  $("#count_RawData").html("(" + dataDates.length + ")");

  $("#filter-button").click(function(e) {

    console.log("Hello world");

    //Gets the form data in a unified manner
    var getFormData = {
      dates: {
        start: $("#date_from").val(),
        end: $("#date_to").val()
      }
    };

    //Function to filter the result
    var filteredData = dateFilterer(dataDates, getFormData.dates.start, getFormData.dates.end);
    preview_json(filteredData.finalValues, $("#view_filteredData")); //show the final result on the screen
    $("#count_FilteredData").html("(" + filteredData.finalValues.length + ")");

  });


});


//Filter function to ensure that the final result set is within a particular range
function dateFilterer(sourceValues, startDate, endDate) {

  /*Curtosy of the tutorial found here: https://www.w3schools.com/jsref/jsref_filter.asp*/
  function filterFunction_dates(sourceValue) {

    //Aim: To test if the tested date is valid within a particular range
    var rangeAcceptance = {
      minValid: new Date(sourceValue.date) >= new Date(startDate),
      maxValid: new Date(sourceValue.date) <= new Date(endDate)
    };

    var acceptanceResult; //boolean to determine if the relevant range specified is valid

    if (startDate != "" && endDate != "") {

      acceptanceResult = (rangeAcceptance.minValid && rangeAcceptance.maxValid);

    } else if (startDate != "") {

      acceptanceResult = rangeAcceptance.minValid;

    } else if (endDate != "") {

      acceptanceResult = rangeAcceptance.maxValid;

    } else {

      acceptanceResult = (1 == 1); //show all results if no specific range has been selected

    }

    return (acceptanceResult);

  }

  /*console.log({

    originalValues: sourceValues,
    finalValues: sourceValues.filter(filterFunction_dates),
    "time of filter": new Date()

  });*/

  //Return the data for display
  return ({

    originalValues: sourceValues,
    finalValues: sourceValues.filter(filterFunction_dates)

  });

}



//Aim: To make the dates into something that the Range filter function can work with
function normalize_date(fieldValue) {

  var monthPossibilities = {
    longStructure: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
    shortStructure: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
  }; //To store what the month values could possibly be for returning their relevant index number

  var datePartitions = fieldValue.split(", ");
  var year = datePartitions[1];
  var month = datePartitions[0].substring(0, 3); //first three characters of section 1

  if (monthPossibilities.longStructure.indexOf(month) > -1) {

    month = (monthPossibilities.longStructure.indexOf(month) + 1).toString(); //Increments by one to give the actual month number

  } else if (monthPossibilities.shortStructure.indexOf(month) > -1) {

    month = (monthPossibilities.shortStructure.indexOf(month) + 1).toString();

  } else {

    month = "";

  }

  //Aim: Add that customary zero to prepend the date value
  if ((month.length < 2) && (month.length > 0)) {

    month = "0" + month;

  }

  var day = datePartitions[0].slice(-2); //last two characters of section 1    
  var finalResult = year + "-" + month + "-" + day;

  return (finalResult);

}




//Aim: Display json in a nicely formatted way
function preview_json(data, target) {

  /*Curtosy of fellow fiddler: http://jsfiddle.net/unLSJ/*/
  var library = {};

  library.json = {
    replacer: function(match, pIndent, pKey, pVal, pEnd) {
      var key = '<span class=json-key>';
      var val = '<span class=json-value>';
      var str = '<span class=json-string>';
      var r = pIndent || '';
      if (pKey)
        r = r + key + pKey.replace(/[": ]/g, '') + '</span>: ';
      if (pVal)
        r = r + (pVal[0] == '"' ? str : val) + pVal + '</span>';
      return r + (pEnd || '');
    },
    prettyPrint: function(obj) {
      var jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg;
      return JSON.stringify(obj, null, 3)
        .replace(/&/g, '&amp;').replace(/\\"/g, '&quot;')
        .replace(/</g, '&lt;').replace(/>/g, '&gt;')
        .replace(jsonLine, library.json.replacer);
    }
  };

  //Show json in desired target
  target.html(library.json.prettyPrint(data));

}
#count_RawData {
  color: #89cbfa;
}

#view_rawData,
#view_filteredData {
  min-height: 50px;
  max-height: 700px;
  overflow-y: scroll;
  width: 100%;
  box-shadow: 0 0 5px #cfcfcf;
  border-radius: 5px;
  border: none;
}

#count_FilteredData {
  color: #498e88;
}

#filter-button {
  width: 100%;
}

#filter_section {
  width: 100%;
  margin-left: auto;
  margin-right: auto;
  padding: 20px;
  /* background-color: #f1f1f1; */
  border: 1px solid #cfcfcf;
}


/*Curtosy of the fellow fiddler's code: http://jsfiddle.net/unLSJ/*/

pre {
  background-color: ghostwhite;
  border: 1px solid silver;
  padding: 10px 20px;
  margin: 20px;
}

.json-key {
  color: brown;
}

.json-value {
  color: navy;
}

.json-string {
  color: olive;
}


/*Update the scrollbar*/

::-webkit-scrollbar {
  width: 7px;
}

::-webkit-scrollbar-track {
  -webkit-box-shadow: inset 0 0 10px rgb(255, 255, 255);
  border-radius: 10px;
}

::-webkit-scrollbar-thumb {
  border-radius: 10px;
  -webkit-box-shadow: inset 0 0 6px rgba(132, 144, 154);
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0" />
  <title>JSON - Date Range Filter Concept</title>

  <!-- CSS  -->
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

  <link href="https://materializecss.com/templates/starter-template/css/style.css" rel="stylesheet" />
  <link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css" rel="stylesheet" />

  <link href="css/style.css" type="text/css" rel="stylesheet" media="screen,projection" />

</head>

<body>

  <nav class="light-blue lighten-1" role="navigation">
    <div class="nav-wrapper container"><a id="logo-container" href="#" class="brand-logo">JSON Date Range Filter</a>
      <ul class="right hide-on-med-and-down">
        <li><a href="#">Home</a></li>
      </ul>

      <ul id="nav-mobile" class="sidenav">
        <li><a href="#">Home</a></li>
      </ul>

      <a href="#" data-target="nav-mobile" class="sidenav-trigger">
        <i class="material-icons">menu</i>
      </a>
    </div>
  </nav>

  <div class="container">

    <div class="section">

      <!--   Raw Data Section   -->
      <div class="row">
        <div class="col s12">
          <div class="icon-block">
            <h4 class="center">Raw Data <small id="count_RawData">(0)</small></h4>
            <pre id="view_rawData" class="light">
              Your raw data will be previewed here
            </pre>
          </div>
        </div>
      </div>

      <!--Filter Form-->
      <div class="row center" id="filter_section">
        <div class="input-field col s6">
          <input id="date_from" type="text" placeholder="From" class="datepicker">
        </div>
        <div class="input-field col s6">
          <input id="date_to" type="text" placeholder="To" class="datepicker">
        </div>
        <button id="filter-button" class="btn-large waves-effect waves-light">Filtra</button>
      </div>

      <!--   Filtered Data Section   -->
      <div class="row">
        <div class="col s12">
          <div class="icon-block">
            <h4 class="center">Filtered Data <small id="count_FilteredData">(0)</small></h4>
            <pre id="view_filteredData" class="light">
              Your final data will be previewed here
            </pre>
          </div>
        </div>
      </div>

    </div>

    <br><br>
  </div>

</body>

</html>


<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script>
<script src="https://materializecss.com/templates/starter-template/js/init.js"></script>

Comments

    Ничего не найдено.