Предположим, у меня есть два таких объекта:

const obj1 = {
  ch1: {
    as: ['a', 'b'],
    ns: ['1']
  }
  ch2: {
    ss: ['#', '*', '+'],
    ts: ['2', '3']
  }
}

const obj2 = {
  ch1: {
    as: ['a', 'g'],
  }
  ch2: {
    ss: ['#', '-', '+'],
    ts: ['1', '5']
  }
}

const result = findSimilarities(obj1, obj2)

Должен вернуть:

[
  'a' // because obj1.ch1.as and obj2.ch1.as contain 'a'
  '#' // because obj1.ch2.ss and obj2.ch2.ss contain '#'
  '+' // because obj1.ch2.ss and obj2.ch2.ss contain '+'
]

Я могу определить уровень 1 как ch1 или ch2, уровень 2 как as, ns, ss или ts, а уровень 3 - строки внутри массивы.

Так что меня интересуют значения на уровне 3, которые есть у этих двух объектов.

Честно говоря, не знал, с чего начать ..

1
whitecircle 8 Июл 2021 в 15:05

5 ответов

Лучший ответ

Я также хочу оставить здесь свое решение. Он будет правильно работать со структурами данных, как вы описали выше. На любой глубине объекта и если массивы будут содержать только примитивные значения.

function findSimilarities(obj1, obj2) {
    if (obj1 instanceof Array && obj2 instanceof Array) {
        return findSimilarArrayValues(obj1, obj2)
    }

    if (!obj1 instanceof Object || !obj1 instanceof Object) {
        return [];
    }

    const similarKeys = findSimilarObjectKeys(obj1, obj2);
    return similarKeys.map(key => findSimilarities(obj1[key], obj2[key])).flat()
}

function findSimilarObjectKeys(obj1, obj2) {
    return Object.keys(obj1).filter(key => obj2.hasOwnProperty(key));
}

function findSimilarArrayValues(arr1, arr2) {
    return arr1.filter(item => arr2.includes(item));
}
0
Gilevich Petr 8 Июл 2021 в 12:49

Попробуйте начать с Object.keys , Object.entries и Object.values ​​. Удачи!

0
kirkland 8 Июл 2021 в 12:30
  • Используйте Object.keys, чтобы найти все ключи в первом объекте, Object.protoype.hasOwnProperty(), чтобы проверить, существуют ли эти ключи в объекте 2
  • Повторите это для уровней 1 и 2.
  • Извлеките значения, общие для массивов уровня 3, используя Array.prototype.filter() в массиве из первого объекта, чтобы сохранить только элементы, найденные в его совпадении из второго объекта:
const obj1 = {
  ch1: {
    as: ['a', 'b'],
    ns: ['1']
  },
  ch2: {
    ss: ['#', '*', '+'],
    ts: ['2', '3']
  }
};

const obj2 = {
  ch1: {
    as: ['a', 'g'],
  },
  ch2: {
    ss: ['#', '-', '+'],
    ts: ['1', '5']
  }
};

const result = findSimilarities(obj1, obj2);
console.log(result);

function findSimilarities(x, y) {
  const res = [];
  for (const k1 of Object.keys(x)) { //Level 1
    if (y.hasOwnProperty(k1)) {
      const xo1 = x[k1];
      const yo1 = y[k1];
      for (const k2 of Object.keys(xo1)) { //Level 2
        if (yo1.hasOwnProperty(k2)) {
          const xo2 = xo1[k2];
          const yo2 = yo1[k2];
          if (Array.isArray(xo2) && Array.isArray(yo2)) { //Level 3 are arrays
            const dupXo2 = xo2.filter(el => yo2.includes(el));
            res.push(...dupXo2);
          }
        }
      }
    }
  }
  return res;
}
0
julien.giband 8 Июл 2021 в 13:40

Вот что я бы порекомендовал:

Создание функции позволяет вызвать ее function compare(obj1, obj2), затем создать две Object.values переменных, за которыми следует пустой массив var equivalent = [];

После этого есть функция forEach, которая ищет оба объекта, и конечный продукт должен выглядеть примерно так:

function compare(obj1, obj2) {
  var values1 = Object.values(obj1);
  var values2 = Object.values(obj2);
  var equivalent = [];

  var keys = Object.keys(obj1);
  keys.forEach(k => {
    if (obj1.hasOwnProperty(k) && obj2.hasOwnProperty(k)) {
      if (obj1[k] === obj2[k]) {
        equivalent.push(obj1[k]);
      }
    }
  });

  console.log(equivalent);
}

compare(obj1, obj2);
1
BeerusDev 8 Июл 2021 в 12:30

Я бы начал с функции function getMatches(obj1, obj2) { ....

Перебирайте ключи первого уровня obj1 с помощью Object.keys(obj1).foreach( key2 => .... (2 для обозначения того, что вы называете уровнем 2)

Затем переберите ЭТИ ключи, Object.keys(obj1[key2]).foreach(key3 > ...

Итак, теперь у вас есть массив, к которому вы можете получить доступ через obj1[key2][key3], и вы можете получить доступ к массиву для сравнения через obj2[key2][key3]. Итак, теперь вам просто нужно перебрать каждое значение в obj1[key2][key3] и проверить, находится ли оно в obj2[key2][key3]. Если ключ находится в обоих, разбейте его в массив, а затем верните массив в конце функции

[править] вам, возможно, придется использовать какую-то проверку или дополнительный оператор цепочки ?., чтобы получить доступ к ключам на obj2, в случае, если есть ключ на obj1, которого нет на obj2

1
TKoL 8 Июл 2021 в 12:24