检查数组是否包含没有引用的对象

时间:2016-05-13 12:58:48

标签: javascript arrays

我有以下功能:

function containsObject(object, array) {
    for (var i = 0; i < array.length; i++) {
        if (array[i] === object) {
            return i;
        }
    }

    return false;
}

以下数组:

var array = [
    {
        name: 'test1',
        age: 12
    },
    {
        name: 'test2',
        age: 14
    }
];

我需要检查以下对象是否在数组中:

var object = {
    name: 'test1',
    age: 12
};

但是当我使用该函数来检查数组是否包含对象时:

console.log(containsObject(object, array));

它将返回false,因为对象的引用不相同。从技术上讲,这些对象并不相同。

如何在不分享参考的情况下继续这样做?

4 个答案:

答案 0 :(得分:2)

小提琴:https://jsfiddle.net/thatOneGuy/3ys6s7sy/2/

您必须使用另一个对象的每个元素检查对象的每个元素。

function containsObject(object, array) {
  for (var i = 0; i < array.length; i++) {
    var count = 0;
    var matching = true;
    for (var key in object) {
      if (array[i][key] === object[key]) {
        matching = true;
        if (count == Object.keys(array[i]).length - 1 && matching) {
          return i;
        } else {
          count++;
        }
      } else {
        matching = false;

      }
    }
  }
  return false;
}

var array = [{
  name: 'test2',
  age: 14
}, {
  name: 'test1',
  age: 12
}];

var thisObject = {
  name: 'test1',
  age: 12
};

console.log(containsObject(thisObject, array));

我改变了数据,看它是否有效。它现在记录了我的#i;正确。如果您要比较大量数据,这将非常慢。你总是可以对两个对象进行字符串化并比较两个字符串吗?

这是该功能:

function containsObject(object, array) {
  for (var i = 0; i < array.length; i++) {
    for (var key in object) {
      //if (array[i][key] === object[key]) {
      //  return i;
      //}
      if (JSON.stringify(array[i]) === JSON.stringify(object)) {
            return i;
        }
    }
  }
  return false;
}

正如评论中所提到的,第一个不适合进行深度比较。而stringify会。我会小心对象的顺序不同。例如,如果您使用此对象:

var thisObject = {
  age: 12,
  name: 'test1'
};

比较一下,它不会像直接的字符串比较一样工作。

使用stringify:https://jsfiddle.net/thatOneGuy/3ys6s7sy/1/

答案 1 :(得分:0)

我最终选择了theOneGuy的解决方案,改变它以便它可以搜索数组和对象:

function containsObject(needle, haystack) {
    for (var i in haystack) {
        var count    = 0,
            matching = true;

        for (var key in needle) {
            if (haystack[i][key] === needle[key]) {
                matching = true;

                if (count == Object.keys(haystack[i]).length - 1 && matching) {
                    return i;
                } else {
                    count++;
                }
            } else {
                matching = false;
            }
        }
    }

    return false;
}

答案 2 :(得分:0)

最好通过Array.prototype.contains()的发明来完成。所以让我们发明它。但是,我将使用我之前的发明Object.prototype.compare()Array.prototype.compare()

Object.prototype.compare = function(o){
  var ok = Object.keys(this);
  return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false;
};
Array.prototype.compare = function(a){
  return this.every((e,i) => typeof a[i] === "object" ? a[i].compare(e) : a[i] === e);
};
Array.prototype.contains = function(o){
  return this.some(e => typeof o === "object" ? o.compare(e) : o === e);
}

var arr = [
           {
            name: 'test1',
             age: 12
           },
           {
            name: 'test2',
             age: 14
           }
          ],
   obj1 = {
           name: 'test1',
            age: 12
          },
   obj2 = {
           name: 'test1',
            age: 11
          }, 
   arr2 = [1,2,3];

document.writeln(arr.contains(obj1));
document.writeln(arr.contains(obj2));
document.writeln(arr2.contains(3));
document.writeln(arr2.contains(4));

当然,你可以修改它以获得索引或找到匹配的参考。

答案 3 :(得分:0)

使用Object.keysArray.sort函数的解决方案。
我已经扩展了您的初始数组以获得更复杂的示例:

function containsObject(object, array) {
    var props = Object.keys(object),
        len = array.length,
        props_count = props.length, inner_obj, inner_props, inArray = false;
    props.sort();

    while (len--) {
        inner_obj = array[len];
        inner_props = Object.keys(inner_obj);
        inner_props.sort();
        if (props_count === inner_props.length) {
            while (props_count--) {
                if (object[props[props_count]] !== inner_obj[inner_props[props_count]]) {
                    break;
                }
                inArray = true;
            }
            if (inArray) return len;  // return array key which has an equal object
            props_count = props.length;
        }
    }

    return false;
}

var array = [{ name: 'test3', age: 12 }, { name: 'test2',  age: 14 }, { name: 'test1',  age: 12 }],
    object = { name: 'test1', age: 12 };

console.log(containsObject(object, array));  // 2 - appropriate key