Typescript: как найти подходящие свойства между 2 объектами - PullRequest
0 голосов
/ 05 апреля 2019

У меня есть 2 объекта, которые имеют вложенные свойства, такие как:

const obj1 = {
   prop1: {
     val1: 10,
     val2: 11,
     val3: 12,
   },
   prop2: {
     val1: 10,
     diff1: true,
   },
   prop4: {
     text1: 't1',
     text99: 't1',
   }
};
const obj2 = {
   prop1: {
     val99: 1000,
     val2: 1100,
     val33: 1200,
   },
   anotherOne: {
     val1: 1000,
     diff1: false,
   },
   prop4: {
     check: true,
     text1: 't100',
     text99: 't100',
   }
};

Как узнать, какие свойства являются общими для обоих объектов?т.е. для приведенного выше примера мне интересно получить следующее:

const propertiesInObj1AndObj2 = {
   prop1: {
     val2: '',
   },
   prop4: {
     text1: '',
     text99: '',
   }
};

Есть ли хороший способ получить этот результат?Или мне нужно вручную выполнить итерацию по каждому свойству, найденному в obj1, и выполнить поиск того же свойства в obj2, чтобы узнать, есть ли совпадение?

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Я думаю, что это действительно зависит от ваших вариантов использования ... вам нужно поддерживать массивы? что если оба свойства существуют, но имеют разные типы? и т. д. и т. д.

Вам придется перебирать ключи хотя бы одного из объектов, но, поскольку вас интересует только пересечение наборов ключей, вам не нужно перебирать оба. Конечно, функция должна быть рекурсивной.

Вот одна из возможных реализаций, которая также работает на уровне типов:

type SameKeyThing<T, U> =
    [T, U] extends [object, object] ?
    { [K in (keyof T) & (keyof U)]: SameKeyThing<T[K], U[K]> } : "";

function sameKeyThing<T, U, S=SameKeyThing<T, U>>(x: T, y: U): { [K in keyof S]: S[K] };
function sameKeyThing(x: any, y: any) {
    if ((typeof x !== "object") || (typeof y !== "object")) return "";
    const ret: any = {};
    for (let k in x) {
        if (k in y) {
            ret[k] = sameKeyThing(x[k], y[k]);
        }
    }
    return ret;
}
const propertiesInObj1AndObj2 = sameKeyThing(obj1, obj2);
// inferred as type { prop1: { val2: ""; }; prop4: { text1: ""; text99: ""; }; }
console.log(propertiesInObj1AndObj2);

Это хорошо работает для вашего примера, но, вероятно, имеет странное поведение, если вы бросаете в него крайние случаи (например, эти массивы). Во всяком случае, надеюсь, что это дает вам некоторые идеи. Удачи!

1 голос
/ 05 апреля 2019

O (n2)

рабочий пример https://stackblitz.com/edit/typescript-2uminr

const obj1 = {
   prop1: {
     val1: 10,
     val2: 11,
     val3: 12,
   },
   prop2: {
     val1: 10,
     diff1: true,
   },
   prop4: {
     text1: 't1',
     text99: 't1',
   }
};
const obj2 = {
   prop1: {
     val99: 1000,
     val2: 1100,
     val33: 1200,
   },
   anotherOne: {
     val1: 1000,
     diff1: false,
   },
   prop4: {
     check: true,
     text1: 't100',
     text99: 't100',
   }
};


const duplicate: any[] = [];

Object.keys(obj1).map( ob1 => {
  Object.keys(obj2).map( ob2 => {
    if (match(ob1, ob2)) { duplicate.push(ob2) } 
  });
});

function match(key1: string, key2: string) {
  return (key1 === key2) ? true : false;
}

console.log(duplicate)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...