1

Hello I am working in a project to keep learning js wich is in this URL: http://themapapp.herokuapp.com/ and this is the github page: https://github.com/xtatanx/mapApp

In some of the parts of my code I need to check if some property already exists in an array of objects and also I that property value is equal to something, so far the code that I am using to to dis is this one:

// check if property value exist  in an array of objects
    function searchByValue(value, property, array){
        for(var i = 0; i < array.length; i++){
            if(array[i][property] === value){
                return true;
            }
        }
        return false;
    }

And I use it like this:

if(searchByValue('myDestiny', 'id', map.markers)){
    map.markers[1].setPosition({
        lat: results[0].geometry.location.k,
        lng: results[0].geometry.location.A
    });
}else{
    createMarker(results[0].geometry.location.k, results[0].geometry.location.A, 'myDestiny');

My question is if actually I am doing it the way it is or if I am wrong because I sometime think that the function its not returning the correct value or is not working good, I will appreciate if some of you guys could give me some advice in how to achieve this, or improve it.

EDIT

i finished with something like

Array.prototype.searchBy = function(property, value){
  var _property = arguments[0];
  var _value = arguments[1];

  if(arguments.length === 1){
    return Array.prototype.indexOf.apply(this, arguments);
  }

  for(var i = 0; i < this.length; i++){
    if(this[i][_property] === _value ){
      return true;
    }
  }

  return false;

};

Didnt used the checkprop part because actually doesnt understood how it works o_O. thank you very much to @GameAlchemist and @jshanley

0

2 Answers 2

2

Your code works well as long as every object in the array you are searching has defined the property you check for. I could see running into a problem otherwise. You might try adding a check that the property is defined before trying to access its value, like this:

function searchByValue(value, property, array){
    for(var i = 0; i < array.length; i++){
        // check that property is defined first
        if(typeof array[i][property] !== 'undefined') {
            // then check its value
            if(array[i][property] === value){
                return true;
            }
        }
    }
    return false;
}
Sign up to request clarification or add additional context in comments.

Comments

1

I would rather define this function as a method of Array, and why not overload indexOf, that would act as std indexOf with one argument, and as indexOf(value, propertyName, checkProp) with three arguments.

var __oldIndexOf = Array.prototype.indexOf ;
Array.prototype.indexOf = function() {
   if (arguments.length==1) return __oldIndexOf.apply(this, arguments);
   var value     = arguments[0];
   var property  = arguments[1];
   var checkProp = arguments[2];
   if (!checkProp) {
        for(var i = 0; i < this.length; i++){
             if(this[i][property] === value){
                 return i;
             }
   } else {
        for(var i = 0; i < this.length; i++){
             var thisItem = this[i] ;
             if (!Object.hasOwnProperty(thisItem, property)) 
                  throw('indexOf error : object ' + thisItem + ' has no property ' + property);
             if(this[i][property] === value){
                 return i;
             }
   }
   return -1;
};

so, for your code,

if (searchByValue('myDestiny', 'id', map.markers)) { ...

becomes :

if (map.markers.indexOf('myDestiny', 'id') != -1 ) { ...

and obviously you can store the found index in case you need it.
i think that, in your case, what you meant was rather using the found index :

var destinyIndex = map.markers.indexOf('myDestiny', 'id');
if(destinyIndex != -1){
   map.markers[ destinyIndex ].setPosition({
                                           lat: results[0].geometry.location.k,
                                           lng: results[0].geometry.location.A
                                          });
} else {
   createMarker(results[0].geometry.location.k, results[0].geometry.location.A, 
                 'myDestiny');
}

Edit : idea of checking that property exists is courtesy of @jshanley

10 Comments

This looks great, i was also thinking in extend the prototype of Array, you just read my mind!
I would be cautious about altering the prototype of the native Array. Especially since OP mentioned that the project is meant to continue learning the js language, and is an open source project. If other folks come by the code and see that Array.indexOf takes multiple arguments, they might be confused when that doesn't work for them.
@jshanley i forgot to mention that -with all due respect- i don't give a dawn about turning into a toad if i change core prototypes. 99.999% project won't get big enough to get that issue, and someone working on a that-big-size project won't look for such answers on stack overflow.
You won't turn into a toad. To my mind, there's nothing wrong with altering the prototype if you have a good reason to do it. I do think that it should be avoided when there is a simple solution available that does not alter the prototype, however, and is not a habit I would recommend someone develop who is trying to learn the language.
Probably just instead of override indexOf i just could add searchByValue as another method, to avoid problems if someone try to use indexOf....also you were kind of rude :( ahahahah
|

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.