如何通过两个对象打字稿角度6进行比较
Posted
技术标签:
【中文标题】如何通过两个对象打字稿角度6进行比较【英文标题】:How to compare by two objects typescript angular6 【发布时间】: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;
【问题讨论】:
请标记有效答案 【参考方案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 中(如果两个对象的键顺序相同):使用
JSON.stringify(obj1) === JSON.stringify(obj2)
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
使用 Lodash ,无论键的顺序如何
_.isEqual(obj1 , obj2 ); // true
分别比较对象的每个键
【讨论】:
【参考方案3】:对于 Angular 使用 Deep Equal
import * as deepEqual from "deep-equal";
console.log(deepEqual(a:123,a:123)); // True
【讨论】:
当心。deepEqual
被 deepStrictEqual
替换,返回类型不是 bool,而是一个 asswerts,如下所示:function deepStrictEqual<T>(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]);
);
【讨论】:
以上是关于如何通过两个对象打字稿角度6进行比较的主要内容,如果未能解决你的问题,请参考以下文章