0

I currently have a method to search some product data which looks similar to this

function search(title) {
  var result = [];
   for (i = 0; i < data.length; i++) {
          if (data[i].title.indexOf(title) > -1) {
              result.push(data[i]);
             }
        }
     return result;
}

Which works when trying to search my data for a product whose title contains the title being searched for. The title is passed in via an input.

However, I would to be able to perform a search for multiple properties and not just the title.

So, for example, say If I have 4 inputs like title, id, location, price and you can search for as many or as few of these as you like. So you can search for one at a time, two at time etc...

How should I approach this without having to write a completely new function? Would it be something similar like

function search(params) {
  var result = [];
   for (i = 0; i < data.length; i++) {
          if (look for all params being searched for here) {
              result.push(data[i]);
             }
        }
     return result;
}

Edit: Just to show how I would pass the data

View

<input ng-model="params.one">

<input ng-model="params.two">

<input ng-model="params.three">

<input ng-model="params.four">

Controller

$scope.search = function() {
   var params = $scope.params;
   // call search service which uses the above function...
}
3
  • That's essentially how you would do it. Depending on how you take input and how flexible you want it to be, you may need another inner loop to do all the comparisons. Commented Nov 11, 2015 at 22:12
  • Is params an object? Can you clarify this? Commented Nov 11, 2015 at 22:13
  • Added an edit there to show what i'm trying to do! Commented Nov 11, 2015 at 22:19

1 Answer 1

1

So let's assume your example looks like this:

var data = [{"title": "foo", "description": "blabla", "yada": "yada"}, {..}];

and now you want to call

search({"title": "f", "yada": "da"});

To find elements with titles that include "f" and all elements with yadas that contain "da". Let's divide and conquer. First we create a method that tells us whether an item matches your search or not:

function matchItem(item, searchParams) {
  for(var propertyToLookFor in searchParams) {
    var valueToLookFor = searchParams[propertyToLookFor];
    if (item[propertyToLookFor].indexOf(valueToLookFor) >= 0) {
      return true;
    }
  }
  return false;
}

What you need to know is of course the for-in loop which iterates over the properties of an object. And objects can be accessed just like arrays, using properties as indexes. So myObject.foo is the same as myObject['foo'] which is the same as var someVar = 'foo'; myObject[someVar];

Now the simplest thing to apply the matcher we created is to use built in filter-method of arrays:

var filteredResult = data.filter(function(item) {
  return matchItem(item, {"title": "f", "yada": "da"});
});

however you can also slightly adapt your method which searched only for title:

function search(searchParams) {
  var result = [];
  for (i = 0; i < data.length; i++) {
    if (matchItem(data[i], searchParams)) {
      result.push(data[i]);
    }
  }
  return result;
}

AngularJS

Since you obviously use angularJS: Angular has a built-in filter filter which already does pretty much everything I just described. Use it like this:

var filteredData = $filter('filter')(data, {"title": "f", "yada": "da"})

Actually the API reference of filter includes an example that looks pretty much exactly like what you are trying to do, including the HTML.

Sign up to request clarification or add additional context in comments.

3 Comments

great answer! Don't have time to give it a bash tonight but i'll let you know tomorrow for sure!
In the matchItem function should it all be searchParams? Or are searchParams and params two different things in that instance?
@user2085143: Yes, all searchParams. I edited my post above for clarification and also added some params I was missing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.