Search within a multi-dimensional array

I’m trying to create a search where depending depending on the checkboxes selected it will only show the facilities that have those amenities. e.g. if bathroom and showers are selected, only facilitys that have both of those show up.

HTML

    <div id="amenitiesList">
     <input type="checkbox" value="1"> Bathrooms<br>
     <input type="checkbox" value="2"> Showers<br>
    <input type="checkbox" value="3">Electricity<br>
<div>
        <div id="parkSearchControls">
          <input type="button" id="parkSearchButton" value="Search" />
          <input type="button" id="parkClearButton" value="Clear" />
        </div>

<h3>Park Results</h3>
<ul id="parkResults">
    
</ul>

JavaScript:

var parksData = new Array (
 {
        'name':'park 1',
        'url':'#',
        'amenities':'1'
    },
 {
        'name':'park2',
        'url':'#',
        'amenities':'1,2'
    },
 {
        'name':'park3',
        'url':'#',
        'amenities':'2,3'
    },
);

$('#parksSearchButton').click(function() {
    
var selectedItems = new Array();
$('#amenitiesList input:checked').each(function() {
    selectedItems.push($(this).val());
});
var selectedAmenities = selectedItems.join(',');
    
    for (var x = 0; x < parksData.length; x++) {
        if ($.inArray(selectedAmenities, parksData[x].amenities) != -1){
            $('#parkResults').append('<li>' +parksData[x].name+ '</li>');
        }        
    } 

});

I know i’m doing something pretty wrong, but i’m not used to working with multi-dimensional arrays.

Hi,

You can do it as follows:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Filter Results</title>
  </head>

  <body>
    <form>
      <div id="amenitiesList">
        <label><input type="checkbox" value="1">Bathrooms</label><br>
        <label><input type="checkbox" value="2">Showers</label><br>
        <label><input type="checkbox" value="3">Electricity</label>
      </div>
      <div id="parkSearchControls">
        <input type="button" id="parkSearchButton" value="Search" />
        <input type="reset" id="parkClearButton" value="Clear" />
      </div>
    </form>
    <ul id="parkResults"></ul>

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>
      var parks = {
        'park 1': {
          'url':'#',
          'amenities': [1]
        },
        'park 2': {
          'url':'#',
          'amenities': [1,2]
        },
        'park 3': {
          'url':'#',
          'amenities': [2,3]
        }
      }

      $('#parkSearchButton').on("click", function(){
        $('#parkResults').empty();

        var desiredAmenities = [];
        $("#amenitiesList input:checked").each(function(){
          desiredAmenities.push(Number(this.value));
        });
        for (var hotel in parks) {
          if (parks.hasOwnProperty(hotel)){
            var hits = parks[hotel].amenities.filter(function(n) {
              return desiredAmenities.indexOf(n) !== -1
            });
          }
          if (hits.length !== 0){
            $('#parkResults').append('<li>' + hotel + '</li>');
          }
        }
      });

      $('#parkClearButton').on("click", function(){
        $('#parkResults').empty();
      });
    </script>
  </body>
</html>

This involves you saving the data as a normal object, which then contains further objects relating to the hotels.

Here’s a demo for you to play around with:

I strongly recommend Lodash. https://lodash.com/

You get god-like collection powers :slight_smile:

2 Likes

That’s a good recommendation.

Would you care to rewrite my example using LoDash, to demonstrate these powers?
I for one would be very interested to see that.

Here: http://jsfiddle.net/k9rvf50r/

Thanks. I’ll have a play with that.

For the OP, I updated my original demo to incorporate this: http://jsfiddle.net/hibbard_eu/09d8jdgs/2/

1 Like

Thank you so much! this was a huge help, i appreciate it! :smile:

so just so i fully understand what’s goign on with your code.
Is it creating a new array with the lodash called “hotel”?

With reference to this code:

var parksData = [
  { name:'park1', url:'#', amenities: [1] },
  { name:'park2', url:'#', amenities: [1, 2] },
  { name:'park3', url:'#', amenities: [2, 3] },
  { name:'park4', url:'#', amenities: [1, 4] },
  { name:'park5', url:'#', amenities: [1, 2, 4] }
];

function find(inputs) {
    return _.filter(parksData, function (hotel) {
        return _.intersection(hotel.amenities, inputs).length === inputs.length;
    });
}

$('#parkSearchButton').on("click", function () {
    $('#parkResults').empty();

    var desiredAmenities = [];
    $("#amenitiesList input:checked").each(function () {
        desiredAmenities.push(Number(this.value));
    });

    $.each(find(desiredAmenities), function (index, hotel) {
        $('#parkResults').append('<li>' + hotel.name + '</li>');
    });
});

$('#parkClearButton').on("click", function () {
    $('#parkResults').empty();
});
  • We now have an array of object, each of which represents a hotel.
  • We get the desired amenities by grabbing any checked inputs when the user presses submit, then convert their values to numbers (they would otherwise be strings) and add them to a desiredAmenities array.
  • After that we pass the desiredAmenities array to the find function, which returns those objects, whose amenities array, include all of the elements in the desiredAmenities array we passed in. No new arrays are being created.
  • We then iterate over the return value of find() and append a <li> element to the list for each one.

Does that make sense?

yes thank you!

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.