【问题标题】:Compare property value in an array of objects比较对象数组中的属性值
【发布时间】:2014-06-02 00:43:19
【问题描述】:

您好,我正在从事一个项目以继续学习 js,网址为:http://themapapp.herokuapp.com/,这是 github 页面:https://github.com/xtatanx/mapApp

在我的代码的某些部分中,我需要检查某个属性是否已经存在于对象数组中,并且我该属性值是否等于某个值,到目前为止,我用来 dis 的代码就是这个:

// 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;
    }

我是这样使用它的:

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');

我的问题是,如果我真的按照它的方式做,或者我错了,因为我有时认为该函数没有返回正确的值或工作不正常,如果你们中的一些人可以提供,我将不胜感激关于如何实现或改进它的一些建议。

编辑

我完成了类似的事情

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;

};

没有使用 checkprop 部分,因为实际上不了解它是如何工作的 o_O。非常感谢@GameAlchemist 和@jshanley

【问题讨论】:

    标签: javascript arrays node.js object for-loop


    【解决方案1】:

    我宁愿把这个函数定义为 Array 的一个方法,为什么不重载 indexOf,它将充当带有一个参数的 std indexOf,以及带有三个参数的 indexOf(value, propertyName, checkProp)。

    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;
    };
    

    所以,对于您的代码,

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

    变成:

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

    显然您可以存储找到的索引以备不时之需。
    我认为,就您而言,您的意思是使用找到的索引:

    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');
    }
    

    编辑:检查属性是否存在的想法是由@jshanley 提供的

    【讨论】:

    • 这看起来很棒,我也在考虑扩展Array的原型,你只是看我的想法!
    • 我会谨慎修改原生 Array 的原型。特别是因为OP提到该项目旨在继续学习js语言,并且是一个开源项目。如果其他人通过代码看到 Array.indexOf 接受多个参数,他们可能会因为这对他们不起作用而感到困惑。
    • @jshanley 我忘了提到——恕我直言——如果我改变核心原型,我不会想到变成蟾蜍。 99.999% 的项目不会变得足够大来解决这个问题,并且从事大型项目的人不会在堆栈溢出时寻找这样的答案。
    • 你不会变成蟾蜍。在我看来,如果你有充分的理由去做,那么改变原型并没有错。我确实认为,当有一个不改变原型的简单解决方案可用时,应该避免这种情况,但是,这不是我建议尝试学习该语言的人养成的习惯。
    • 可能只是代替覆盖 indexOf 我只是可以添加 searchByValue 作为另一种方法,以避免有人尝试使用 indexOf....
    【解决方案2】:

    只要您正在搜索的数组中的每个对象都定义了您要检查的属性,您的代码就可以正常工作。否则我可能会遇到问题。您可以尝试在尝试访问其值之前添加一个检查该属性是否已定义,如下所示:

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-28
      • 1970-01-01
      • 2018-12-30
      相关资源
      最近更新 更多