【问题标题】:How to compare by two objects typescript angular6如何通过两个对象打字稿角度6进行比较
【发布时间】:2019-02-02 14:45:55
【问题描述】:

我想比较两个 Json 对象数组。一个有更多的数据。对于最终结果,如果一个 id 找到另一个,则选中的复选框 = true。到目前为止有4个,它只找到一个。我是否先循环遍历长数组,然后循环遍历第二个数组以查找匹配项?

 this.formAll = JSON.parse(response)
      for (var i = 0; i < this.formAll.length; i++) {
        for (var j = i; j <  this.formAb.length; j++) {
         console.log( this.formAb[j].id,  this.formAll[i].SeriesNumber);
          if ( this.formAll[i].id === this.formAb[j].id) {
            console.log( 'small=', this.formAb[j].id, 'large=', 
         this.formAll[i].id );
         this.formAll[i].selected = true;
        }}
      }

【问题讨论】:

  • 请标记有效答案

标签: javascript arrays angular typescript


【解决方案1】:

快速而有限

JSON.stringify(obj1) === JSON.stringify(obj2)

缓慢而通用

Object.equals = function( x, y ) {
    if ( x === y ) return true;
    // if both x and y are null or undefined and exactly the same

    if ( ! ( x instanceof Object ) || ! ( y instanceof Object ) ) return false;
    // if they are not strictly equal, they both need to be Objects

    if ( x.constructor !== y.constructor ) return false;
    // they must have the exact same prototype chain, the closest we can do is
    // test there constructor.

    for ( var p in x ) {
        if ( ! x.hasOwnProperty( p ) ) continue;
        // other properties were tested using x.constructor === y.constructor

       if ( ! y.hasOwnProperty( p ) ) return false;
       // allows to compare x[ p ] and y[ p ] when set to undefined

       if ( x[ p ] === y[ p ] ) continue;
       // if they have the same strict value or identity then they are equal

       if ( typeof( x[ p ] ) !== "object" ) return false;
       // Numbers, Strings, Functions, Booleans must be strictly equal

       if ( ! Object.equals( x[ p ],  y[ p ] ) ) return false;
       // Objects and Arrays must be tested recursively
   }

   for ( p in y ) {
      if ( y.hasOwnProperty( p ) && ! x.hasOwnProperty( p ) ) return false;
      // allows x[ p ] to be set to undefined
    }
    return true;
}

【讨论】:

  • 不要向内置运行时实体添加属性。此属性将来可能会成为标准,不一定以相同的方式实现。
【解决方案2】:

在 Javascript/Typescript 中(如果两个对象的键顺序相同):使用

  1. JSON.stringify(obj1) === JSON.stringify(obj2)
  2. Object.entries(obj1).toString() === Object.entries(obj2).toString()

obj1 = { a:1, b:2 }obj2 = { a:1, b:2 }// true

obj1 = { a:1, b:2 }obj2 = { b:2, a:1 }// false

  1. 使用 Lodash ,无论键的顺序如何

    _.isEqual(obj1 , obj2 ); // true

  2. 分别比较对象的每个键

【讨论】:

    【解决方案3】:

    对于 Angular 使用 Deep Equal

    import * as deepEqual from "deep-equal";
    
    console.log(deepEqual({a:123},{a:123})); // True
    

    【讨论】:

    • 当心。 deepEqualdeepStrictEqual 替换,返回类型不是 bool,而是一个 asswerts,如下所示:function deepStrictEqual&lt;T&gt;(actual: any, expected: T, message?: string | Error): asserts actual is T; 在此处阅读有关 asserts 的更多信息:typescriptlang.org/docs/handbook/release-notes/…
    【解决方案4】:

    简单易行!!

    如果对象键相同且有序,JSON.stringify(Obj2) 工作最快:

    Obj1 = { fruit: '?' };
    Obj2 = { fruit: '?' };
    
    JSON.stringify(Obj1) === JSON.stringify(Obj2);

    【讨论】:

    • 这个答案已经给出,请尝试解释更多,否则这个答案将无济于事。
    • 并非总是如此。如果你对两个对象进行字符串化,属性中的顺序可能不一定是相同的,这意味着两个字符串会有很大的不同
    【解决方案5】:

    您可以使用 for-of 和 find 方法获得结果,例如:

    for(let item  of this.formAll) {
        if (this.formAb.find((i) => { i.id === item.id})){
           item.selected = true;
        }
    }
    

    【讨论】:

      【解决方案6】:

      使用过滤器效果更好。

         this.formAll = JSON.parse(response)
          this.formAll.forEach((element) => {
            this.formAb.filter((element1) => {
              if (element1.id === element.id ) {
                element.selected = true;
              }
           })
           })
      

      【讨论】:

        【解决方案7】:

        比较两个 Json 对象的例子: 对象 1:

        {
        id : 1,
        name : 'HADY',
        status : false
        }
        

        对象 2:

        {
        id : 1,
        name : 'example',
        surename : 'example',
        nickname : 'example'
        status : true
        }
        

        ----------------------------------------------- -比较(obj1,obj2){

          const keys1 = [];
            const values1 = [];
            Object.keys(obj1).forEach((element) => {
              keys1.push(element);
            });
            Object.values(obj1).forEach((element) => {
              values1.push(element);
            });
            const keys2 = [];
            const values2 = [];
            Object.keys(obj2).forEach((element) => {
              keys2.push(element);
            });
            Object.values(obj2).forEach((element) => {
              values2.push(element);
            });
            const obj = {};
            keys1.forEach((element, i) => {
              for (let index = 0; index < keys2.length; index++) {
                if (element === keys2[index]) {
                  if (values1[i] !== values2[index]) {
                    const jsonKey = element;
                    obj[jsonKey] = values1[i];
                  }
                  break;
                }
              }
            });
            console.log(obj);
            return obj;
          }
        

        它只会返回尊重: 对象

        {
        name : 'HADY',
        status : false
        }
        

        【讨论】:

          【解决方案8】:

          我认为比较“JSON.Stringify”方法不正确; 下一个检查递归对象的变体:

          interface IComparator<T> {
            equals(obj: T, other: T): boolean;
          }
          
          export default class Comparator<T> implements IComparator<T> {
            equals(item: T, otherItem: T): boolean {
              if (typeof item !== typeof otherItem) {
                return false;
              }
          
              const objectCache: any[] = [];
              const otherObjectCache: any[] = [];
              const getIndexFromCache = (compareObject: any, cacheArray: any[]): number =>
                cacheArray.findIndex((item) => item === compareObject);
          
              switch (true) {
                case item === otherItem:
                  return true;
                case typeof item !== 'object':
                  return item === otherItem;
                case item === null || otherItem === null:
                  return item === null && otherItem === null;
                case Object.keys(item).length !== Object.keys(otherItem).length:
                  return false;
                default:
                  const object = item as any;
                  const otherObject = otherItem as any;
          
                  return Object.keys(object).every((key: string) => {
                    const hasKeyInOtherObject = Object.prototype.hasOwnProperty.call(otherItem, key);
          
                    if (!hasKeyInOtherObject) {
                      return false;
                    }
          
                    const cacheObjectIndex = getIndexFromCache(object[key], objectCache);
                    const cacheOtherObjectIndex = getIndexFromCache(otherObject[key], otherObjectCache);
          
                    if (cacheObjectIndex !== cacheOtherObjectIndex) {
                      return false;
                    }
          
                    const isEqualsCacheObjects =
                      cacheObjectIndex !== -1 && cacheOtherObjectIndex !== -1 && cacheObjectIndex === cacheOtherObjectIndex;
          
                    if (isEqualsCacheObjects) {
                      return true;
                    }
          
                    objectCache.push(object[key]);
                    otherObjectCache.push(otherObject[key]);
          
                    return new Comparator<any>().equals(object[key], otherObject[key]);
                  });
              }
            }
          }
          

          并开玩笑地测试它:

          import Comparator from './Comparator';
          
          export default describe('Comparator', () => {
            const recursiveA: { value: number; b?: any } = { value: 1 };
            const recursiveB: { value: number; a?: any } = { value: 2 };
          
            recursiveA.b = recursiveB;
            recursiveB.a = recursiveA;
          
            it.each([
              [null, null, true],
              [undefined, undefined, true],
              [1, 1, true],
              ['test', 'test', true],
              [[1, 2], [1, 2], true],
              [{ a: 1, b: 3 }, { a: 1, b: 3 }, true],
              [2, 1, false],
              ['test', 'test2', false],
              [[1, 2], [2, 1], false],
              [{ a: 1, b: 3 }, { a: 3, b: 1 }, false],
              [recursiveA, recursiveB, false],
              [null, 1, false],
              [null, {}, false],
              [undefined, null, false],
              [1, '1', false],
            ])('compares values %o and %o are equal: %s', (value1: any, value2: any, expectedResult: boolean) => {
              const comparator = new Comparator<any>();
              const actualResult = comparator.equals(value1, value2);
          
              expect<boolean>(actualResult).toBe(expectedResult);
            });
          });
          

          和Javascript版本:

          export default class Comparator {
              equals(item, otherItem) {
                  if (typeof item !== typeof otherItem) {
                      return false;
                  }
          
                  const objectCache = [];
                  const otherObjectCache = [];
                  const getIndexFromCache = (compareObject, cacheArray) => cacheArray.findIndex((item) => item === compareObject);
          
                  switch (true) {
                      case item === otherItem:
                          return true;
                      case typeof item !== 'object':
                          return item === otherItem;
                      case item === null || otherItem === null:
                          return item === null && otherItem === null;
                      case Object.keys(item).length !== Object.keys(otherItem).length:
                          return false;
                      default:
                          const object = item;
                          const otherObject = otherItem;
          
                          return Object.keys(object).every((key) => {
                              const hasKeyInOtherObject = Object.prototype.hasOwnProperty.call(otherItem, key);
          
                              if (!hasKeyInOtherObject) {
                                  return false;
                              }
          
                              const cacheObjectIndex = getIndexFromCache(object[key], objectCache);
                              const cacheOtherObjectIndex = getIndexFromCache(otherObject[key], otherObjectCache);
          
                              if (cacheObjectIndex !== cacheOtherObjectIndex) {
                                  return false;
                              }
          
                              const isEqualsCacheObjects = cacheObjectIndex !== -1 && cacheOtherObjectIndex !== -1 && cacheObjectIndex === cacheOtherObjectIndex;
          
                              if (isEqualsCacheObjects) {
                                  return true;
                              }
          
                              objectCache.push(object[key]);
                              otherObjectCache.push(otherObject[key]);
          
                              return new Comparator().equals(object[key], otherObject[key]);
                          });
                  }
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2017-09-23
            • 1970-01-01
            • 2021-10-23
            • 2014-02-19
            • 1970-01-01
            • 1970-01-01
            • 2019-07-08
            • 2021-04-25
            • 1970-01-01
            相关资源
            最近更新 更多