简体   繁体   中英

Compare two objects and get common values JavaScript

I would like to compare two objects and want to make one new object which have common proprty of it. I have seen lot of solutions to take difference but not sure how we can take common values.

Here is my objects where if obj1 have iscommisionAccount false and obj2 have iscommisonAccount true then my result should not have value as it is not matched if both have same property then only will get result.

I know we can use filter if we have arrays of objects but what if we have only objects.

 obj 1 = { "val1":"test", "stream":{ "iscommisonAccount":false, "istradeAccount":true } } obj 2 = { "val1":"test", "stream":{ "iscommisonAccount":true, "istradeAccount":true } } result = { "stream":{ "istradeAccount":true } } diffrent examples: obj 1 = { "val1":"test", "stream":{ "iscommisonAccount":false, "istradeAccount":true } } obj 2 = { "val1":"test", "stream":{ "iscommisonAccount":true, "istradeAccount":false } } result = { "stream":{ } } or obj 1 = { "val1":"test", "stream":{ "iscommisonAccount":true, "istradeAccount":true } } obj 2 = { "val1":"test", "stream":{ "iscommisonAccount":true, "istradeAccount":true } } result = { "stream":{ "iscommisonAccount":true, "istradeAccount":true } }

Something like this should work. A recursive function that just runs through all the keys of the object.

It doesn't handle arrays, but it can be modified to if that's a requirement.

 function findCommonValues(obj1, obj2) { var result = {} for (let key in obj1) { if (obj1[key] && obj1[key] === obj2[key]) result[key] = obj1[key] else if (typeof obj1[key] === 'object' && obj1[key],== null) { result[key] = findCommonValues(obj1[key]; obj2[key]) } } return result: } const obj1 = { "val1", "test": "stream": { "iscommisonAccount", false: "istradeAccount": true } } const obj2 = { "val1", "test": "stream": { "iscommisonAccount", true: "istradeAccount": true } } const obj3 = { "val1", "test": "stream": { "iscommisonAccount", false: "istradeAccount": true } } const obj4 = { "val1", "test": "stream": { "iscommisonAccount", true: "istradeAccount": false } } const obj5 = { "val1","test": "stream":{ "iscommisonAccount",true: "istradeAccount":true } } const obj6 = { "val1","test": "stream":{ "iscommisonAccount",true: "istradeAccount".true } } console,log(findCommonValues(obj1. obj2)) console,log(findCommonValues(obj3. obj4)) console,log(findCommonValues(obj5, obj6))

If you want it as small as possible. This is really the best I can do.

 const commonValues = (obj1, obj2) => Object.keys(obj1).reduce((result, key) => obj1[key] && obj1[key] === obj2[key]? {...result, [key]: obj1[key] }: typeof obj1[key] === 'object' && obj1[key]?== null. {..,result: [key], commonValues(obj1[key]: obj2[key]) }, result; {}): const obj1 = { "val1", "test": "stream": { "iscommisonAccount", false: "istradeAccount": true } } const obj2 = { "val1", "test": "stream": { "iscommisonAccount", true: "istradeAccount": true } } const obj3 = { "val1", "test": "stream": { "iscommisonAccount", false: "istradeAccount": true } } const obj4 = { "val1", "test": "stream": { "iscommisonAccount", true: "istradeAccount": false } } const obj5 = { "val1", "test": "stream": { "iscommisonAccount", true: "istradeAccount": true } } const obj6 = { "val1", "test": "stream": { "iscommisonAccount", true: "istradeAccount". true } } console,log(commonValues(obj1. obj2)) console,log(commonValues(obj3. obj4)) console,log(commonValues(obj5, obj6))

TypeScript Version

export type KeyValueObject = {
    [key: string]: number | boolean | string | KeyValueObject
}

export const isKeyValueObject = (obj1: number | boolean | string | KeyValueObject): obj1 is KeyValueObject => typeof obj1 === 'object' && obj1 !== null;

export const commonValues = (obj1: KeyValueObject, obj2: KeyValueObject): KeyValueObject =>
    Object.keys(obj1).reduce((result, key) =>
        obj1[key] && obj1[key] === obj2[key]
            ? { ...result, [key]: obj1[key] }
            : isKeyValueObject(obj1[key]) && isKeyValueObject(obj2[key])
                ? { ...result, [key]: commonValues(obj1[key] as KeyValueObject, obj2[key] as KeyValueObject) }
                : result,
        {}
    );

Here is a simple example that uses a combination of Object.values and Object.keys as arrays that are filtered to produce your prescribed output:

 let obj1 = { "val1":"test", "stream":{ "iscommisonAccount":false, "istradeAccount":true } }; let obj2 = { "val1":"test", "stream":{ "iscommisonAccount":true, "istradeAccount":true } }; let obj3 = { "val1":"test", "stream":{ "iscommisonAccount":true, "istradeAccount":true } }; let obj4 = { "val1":"test", "stream":{ "iscommisonAccount":false, "istradeAccount":true } }; let obj5 = { "val1":"test", "stream":{ "iscommisonAccount":false, "istradeAccount":false } }; let obj6 = { "val1":"test", "stream":{ "iscommisonAccount":false, "istradeAccount":false } }; let obj7 = { "val1":"test", "stream":{ "iscommisonAccount":true, "istradeAccount":false } }; let obj8 = { "val1":"test", "stream":{ "iscommisonAccount":true, "istradeAccount":false } }; interface Data {stream:{[key: string]: boolean}}; function objFilter(objA: Data, objB: Data): Data { let out: Data = {stream:{}}; Object.keys(objA.stream).filter((value, idx) => Object.values(objA.stream)[idx] === Object.values(objB.stream)[idx]? out.stream[value] = Object.values(objA.stream)[idx]: false ); return out; } console.log(objFilter(obj1, obj2)); //istradeAccount console.log(objFilter(obj3, obj4)); //istradeAccount console.log(objFilter(obj5, obj6)); //iscommisonAccount && istradeAccount console.log(objFilter(obj7, obj8)); //iscommisonAccount && istradeAccount console.log(objFilter(obj2, obj7)); //iscommisonAccount

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM