Заполните карту на основе другой карты и выбранных значений

1

У меня есть такая Map со мной.

k1: ["x", "y"]
k2: ["x", "z"]
k3: ["x", "y"]
k4: ["x", "z"]
k5: ["x", "z"]
k6: ["k", "a"]
k7: ["m", "b"]

У меня есть список ценностей со мной, как это

[["x", "y"], ["x", "z"]]

У меня также есть еще одна Map со мной, у которой есть те же ключи, что и у первой карты, но разные значения, подобные этому

k1: 0
k2: 0
k3: 0
k4: 0
k5: 0
k6: 0
k7: 0 

Я хочу заменить значение ключей во второй карте на 1 если соответствующее значение этого конкретного ключа на первой карте присутствует в приведенном списке.

Ожидаемый результат выглядит следующим образом:

k1: 1
k2: 1
k3: 1
k4: 1
k5: 1
k6: 0
k7: 0

Я могу достичь этого многократного цикла над ключами карт, но карты, которые у меня есть, очень большие (записи 1M+). Я хочу найти наиболее эффективный метод, который мог бы достичь этого.

Теги:

2 ответа

1
Лучший ответ

Используйте наборы. valsSet только один цикл (кроме неявного цикла, который создает valsSet), а скорость поиска не является проблемой.

EDIT: вопрос был существенно изменен; этот ответ изменяется в ответ. Редактирование было необходимо, потому что, в отличие от строк, где "key2" == "key2", с массивами ["x", "y"] != ["x", "y"], так просто Set поиск (valsLookup.has(["x", "y"])) невозможно.

let a = new Map(Object.entries({
  k1: ["x", "y"], k2: ["x", "z"], k3: ["x", "y"], k4: ["x", "z"], k5: ["x", "z"], k6: ["k", "a"], k7: ["m", "b"]
}));
let b = new Map(Object.entries({
  k1: 0, k2: 0, k3: 0, k4: 0, k5: 0, k6: 0, k7: 0,
}));
let vals = [["x", "y"], ["x", "z"]];

let valsLookup = vals.reduce((m, [x, y], i) => {
  let s = m.get(x);
  if (!s) m.set(x, s = new Set());
  s.add(y);
  return m;
}, new Map());

a.forEach(([x, y], i) => {
  let vx = valsLookup.get(x);
  if (vx && vx.has(y)) b.set(i, 1);
});
console.log(b);
// => Map {
//      'k1' => 1,
//      'k2' => 1,
//      'k3' => 1,
//      'k4' => 1,
//      'k5' => 1,
//      'k6' => 0,
//      'k7' => 0 }
  • 0
    несмотря на то, что он работает с образцом карты, который я вставил в вопрос, который я не могу использовать в работе с реальной картой, над которой я работаю
  • 0
    Я обновляю вопрос. Пожалуйста, держись
Показать ещё 8 комментариев
1

Создайте временный объект для хранения значений списка в качестве объекта для чтения O1.

var listObj = ["val1", "val2"].reduce((acc, item)=>({...acc, [item]: true}), {})

var obj1 = {
	k1: "val1"
}

var obj2 = {k1: 0, k2: 0, k3: 0}

console.log(Object.keys(obj2).reduce((acc, key)=>({...acc, [key]: listObj[obj1[key]] ? 1 : 0}), {}))

Ещё вопросы

Сообщество Overcoder
Наверх
Меню