【问题标题】:Checking if object is already in array not working检查对象是否已经在数组中不起作用
【发布时间】:2017-08-10 18:53:12
【问题描述】:

我正在尝试检查一个对象是否已经在一个数组中,在这里遵循这个答案:How to determine if object is in array

我根据自己的需要调整了功能,现在看起来是这样的:

var _createDatesArray, _objInArray;

_objInArray = function(array, obj) {
  var i;
  i = 0;
  while (i < array.length) {
    console.log("array[i] == obj is ", array[i] === obj, " array[i] is ", array[i], " and obj is ", obj);
    if (array[i] === obj) {
      return true;
    }
    i++;
  }
};

_createDatesArray = function(val) {
  var result;
  if (val != null) {
    result = {
      text: val
    };
    if (!_objInArray(scope.datesQuestion.dates, result)) {
      scope.datesQuestion.dates.push(result);
    }
    return console.log(scope.datesQuestion.dates);
  }
};

我需要做的,基本上就是看看对象是否已经在数组中,如果是,则返回true。

调试时,控制台日志的结果如下:

array[i] == obj 为 false array[i] 为 {text: "10/08/17"} 且 obj 为 {文本:“2017 年 10 月 8 日”}

函数说它们不同 (array[i] == obj is false) 但在我看来它们是一样的。

我还检查了两者的类型,是这样的:

typeof array[i] is "object"
typeof obj is "object"

你能帮我解决这个问题吗?为什么它们不同?有什么不同?

_createDatesArray 在我的 Angular 应用程序的 $scope 基于 ng-model 更改其值时被调用,但我认为这无关紧要

【问题讨论】:

  • 两个对象只有当它们是同一个对象(不同的引用)时才相等。检查{a: 'a'} === {a: 'a'} => 错误。

标签: javascript angularjs arrays


【解决方案1】:

它们是具有相同内容的两个不同对象。将它们与===== 进行比较会得到错误。

由于您使用的是 AngularJS,因此您可以改用angular.equals() 来对对象的属性进行深度比较。

【讨论】:

  • 谢谢 我不知道 angular.equals()。我去看看
【解决方案2】:

您正在比较的对象没有相同的引用,因此== 返回 false。更详细的解释见Object comparison in JavaScript

在这种特殊情况下,您可以简单地比较日期文本以查看它们是否相等。然而,这并不适用于函数名称所暗示的所有对象。

if (arr[i].text === obj.text)

或者,您可以创建一个专门用于检查您的数组是否包含给定日期的方法,并使用Array.prototype.some 大大简化它:

dateInArray = function (array, date) {
  return array.some(function (arrayDate) {
    return arrayDate.text === date.text
  })
}

或者,更简洁地使用 ES6 箭头函数:

dateInArray = (array, date) => array.some(arrayDate => arrayDate.text === date.text)

【讨论】:

    【解决方案3】:

    array[i] === obj 只有当它是同一个对象时才会返回 true。在您提到的链接中,被检查的对象与插入数组中的对象相同,这就是它返回 true 的原因。在您的情况下,您正在创建一个新对象“结果”并在其中添加值。所以数组不包含完全相同的对象,因此返回 false。 如果“文本”是对象中的唯一属性,则可以检查两个对象中的“文本”属性是否相同,而不是检查整个对象。

    _objInArray = function(array, obj) {
      var i;
      i = 0;
      while (i < array.length) {
        if (array[i].text === obj.text) {
          return true;
        }
        i++;
      }
    };
    

    【讨论】:

      【解决方案4】:

      这是因为 JS 中的对象是通过引用进行比较,而不是通过它们的值进行比较。但是您需要按对象的值来比较对象。所以你需要获取一些第三方功能或者自己编写。另一种选择是使用内置的角度equalsfunction

      angular.equals($scope.user1, $scope.user2);
      

      为了更好地理解你可以阅读一篇关于这个主题的好文章here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-03
        • 2011-09-11
        • 1970-01-01
        • 2012-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多