【问题标题】:How to take two objects with the same values, and make it so that they are seen as one single object如何获取具有相同值的两个对象,并使它们被视为一个对象
【发布时间】:2016-04-15 21:35:35
【问题描述】:

我正在创建一个允许手动过滤的多选下拉组件。当项目首次显示时,我正在循环一个对象数组:

   customers = [
       {name: "Boe", city: "Scottsdale", state: "AZ", zip: 45454},
       {name: "Tom", city: "Austin", state: "TX", zip: 34323}
    ]

如果用户在没有过滤的情况下从下拉列表中选择了上面的客户,这是控制台中的对象:

 Object {name: "Boe", city: "Scottsdale", state: "AZ", zip: 46545, $$hashkey: "object 71"}

当设置了手动过滤器时,这允许用户输入的文本过滤下拉列表,以传递到组件外部。自定义过滤器的示例可能如下所示,它很可能会从服务器过滤某些内容,然后发回一个新的对象数组。例如,假设用户在输入中键入字母“b”,上述数据将被过滤以在下拉列表中仅显示“Boe”,下面的匹配数组将仅包含“Boe”

 var matches = [];
 for (var i = 0; i < unfilteredCustomers.length; i++) {
     //filter it
 }
 //update the customers based on each letter that is typed
 $scope.customers = matches;

然后像这样将其传递回组件:

   <dropdown-select items="customers"></dropdown-select>

所以最初,传入的客户是第一个客户数组,一旦用户开始输入以过滤客户,就会更新并传回组件。如果我过滤并选择过滤后的行,控制台中会显示以下内容:

Object {name: "Boe", city: "Scottsdale", state: "AZ", zip: 46545, $$hashkey: "object 170"}

$$hashKey 正在改变。我意识到我基本上发回了一个新数组,该数组改变了它对原始项目集的引用。但是问题该组件的功能是,如果用户过滤并进行选择,则下拉菜单会打开回到其原始项目。所以我遇到的问题是一旦用户选择了一个过滤的项目,并且下拉菜单打开,用户可以再次选择相同的项目,因为“this.selectedItems.indexOf(selectedRow) === -1 没有看到过滤的行与未过滤下拉列表并且用户进行选择时相同。

我怎样才能让这两个对象被认为是完全相同的?

谢谢

【问题讨论】:

    标签: javascript arrays angularjs angularjs-directive filter


    【解决方案1】:

    如果这些对象的所有值都是原始值,你可以这样做

    function areSameObjects(ob1, ob2){
        var areSame = false;
    
        if(Object.keys(ob1).length === Object.keys(ob2).length){
            delete ob1.$$hashkey;
            delete ob2.$$hashkey;
            areSame = Object.keys(ob1).reduce(function(state, key){
                state = Object.is(ob1[key],ob2[key]) && state;
                return state;
            }, true);
        }
    
        return areSame;
    }
    

    【讨论】:

    • 是的,这确实有效。谢谢。我所做的唯一更改是在角度属性上使用“删除”键不会删除该属性。它只会删除您自己创建的属性。在 Angular 中,您可以使用 angular.toJson 从对象中删除 $$haskey 属性。所以我用 "ob1 = angular.toJson(ob1)" 删除了 $hashkey 属性。
    【解决方案2】:

    这不是语言级别的功能。相反,您必须检查值相等。 Lodash 有一个递归检查所有属性和值的方法,以查看是否所有内容都与 https://lodash.com/docs#isEqual 匹配。

    或者,您可以找到一种方法来散列对象,或者只是 JSON.stringify 它们两者并比较这些值。

    【讨论】:

    • 谢谢安迪...我正在使用 angular.equals 应该做同样的事情。但整个问题是我在帖子中列出的这两个对象从来都不是相等的。这是因为 $$haskKey 不同还是因为它们本质上是两个包含相同对象的不同数组?我真的想弄清楚如何使上面的这两个对象相等,因为现在 angular.equals 在我过滤并选择一行时返回 false,并且在未过滤下拉列表时单击同一行,这意味着它们不是一回事。我怎样才能让它们被视为相同?
    猜你喜欢
    • 2020-01-19
    • 1970-01-01
    • 2021-07-18
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多