Предположим, у вас есть два объекта карта, как проверить, совпадают ли их наборы ключей?
Например:
const A = new Map();
A.set('x', 123);
A.set('y', 345);
const B = new Map();
B.set('y', 567);
B.set('x', 789);
const C = new Map();
C.set('x', 121);
C.set('y', 232);
C.set('z', 434);
в этом случае карты A
и B
имеют один и тот же набор ключей (который является ['x', 'y']
), в то время как набор ключей C
отличается, поскольку он имеет дополнительный ключ z
.
вы не можете вызвать .keys().size()
на объекте Map
@SuperDJ специфичен для Map
Я не думаю, что этот вопрос одинаковый, в основном способ ответов будет другим
@ FrancescoBorzì, могу я спросить, почему вы приняли мой длинный и неуклюжий ответ вместо других, которые выглядят короче / чище? (Единственное, что я могу придумать, это сложность ответа, мой больше похож на самообъясняющий псевдокод)
потому что это наиболее понятный ответ: D
Убедитесь, что size
каждой карты одинаков, а затем переберите keys
одного Map
и убедитесь, что ключ существует и в другом. Использование Array.prototype.every.call
означает, что создавать промежуточный массив не нужно:
const A = new Map();
A.set('x', 123);
A.set('y', 345);
const B = new Map();
B.set('y', 567);
B.set('x', 789);
const C = new Map();
C.set('x', 121);
C.set('y', 232);
C.set('z', 434);
const sameKeySet = (m1, m2) => (
m1.size === m2.size
&& Array.prototype.every.call(m1.keys(), key => m2.has(key))
);
console.info(sameKeySet(A, B));
console.info(sameKeySet(A, C));
Что ж, это выглядит определенно чище, чем у меня. Есть ли причина использовать Array.prototype
вместо []
. Также нельзя ли снять скобки (... && ...)
с условием?
Использование Array.prototype.every.call
означает, что нет необходимости создавать промежуточный массив, тогда как что-то вроде [...m1.keys()]
было бы излишне создает новый массив из итератора. Да, было бы синтаксически правильно опустить круглые скобки, но поскольку это многострочное выражение, я думаю, что круглые скобки делают код более понятным для чтения.
А, ладно, я думал о [].every.call
, надеясь, что пустой массив не будет такой большой проблемой и не будет выглядеть «так страшно», как Array.prototype
=) [на самом деле я только хотел сократить его до двух строк]
Вы можете проверить размер, а затем перебрать ключи одной карты и проверить, есть ли они и на другой.
const A = new Map();
A.set('x', 123);
A.set('y', 345);
const B = new Map();
B.set('y', 567);
B.set('x', 789);
const C = new Map();
C.set('x', 121);
C.set('y', 232);
C.set('z', 434);
function sameKeys(a, b) {
if (a.size != b.size) {
return false;
}
for (let key in a.keys()) {
if (!b.has(key)) {
return false;
}
}
return true;
}
console.info(sameKeys(A, B));
console.info(sameKeys(A, C));
Вы можете преобразовать ключи Map в массив, расширив итератор, возвращаемый методом keys()
:
const aKeys = [...A.keys()];
Тогда вам просто нужно будет сравнить все массивы ключей. В случае вашего появления вы можете просто сделать:
const A = new Map();
A.set('x', 123);
A.set('y', 345);
const B = new Map();
B.set('y', 567);
B.set('x', 789);
const C = new Map();
C.set('x', 121);
C.set('y', 232);
C.set('z', 434);
const aKeys = [...A.keys()];
const bKeys = [...B.keys()];
const cKeys = [...C.keys()];
console.info(aKeys.sort().toString() == bKeys.sort().toString());
console.info(aKeys.sort().toString() == cKeys.sort().toString());
console.info(bKeys.sort().toString() == cKeys.sort().toString());
В основном вам нужно проверить две вещи:
const A = new Map();
A.set('x', 123);
A.set('y', 345);
const B = new Map();
B.set('y', 567);
B.set('x', 789);
const C = new Map();
C.set('x', 121);
C.set('y', 232);
C.set('z', 434);
const D = new Map();
C.set('x', 121);
C.set('z', 232);
function isSame(a,b){
if (a.size != b.size)
return false;
for(const [key, value] of a.entries()){
if (!b.has(key))
return false;
}
return true;
}
console.info(isSame(A,B));
console.info(isSame(A,C));
console.info(isSame(A,D));
Вы можете проверить размер и взять прототип has
и вторую карту как thisArg
для проверки всех ключей с помощью Array#some
.
Это работает для любых типов, поскольку не изменяет тип ключей.
const
compare = (a, b) => a.size === b.size && [...a.keys()].some(Map.prototype.has, b),
a = new Map([['x', 123], ['y', 345]]);
b = new Map([['y', 567], ['x', 789]]);
c = new Map([['x', 121], ['y', 232], ['z', 434]]);
console.info(compare(a, b));
console.info(compare(a, c));
Вы можете построить новый Map
с обоими их записями, а затем сравнить размер. В любом случае вам нужно проверить размер их обоих, и если он такой же, то только вы должны продолжить.
map1.size.size
===map2.size &&
new Map([...map1, ...map2])).size
===map1.size
// или map2.size
Создадим рабочий пример:
const A = new Map();
A.set('x', 123);
A.set('y', 345);
const B = new Map();
B.set('y', 567);
B.set('x', 789);
const C = new Map();
C.set('x', 121);
C.set('y', 232);
C.set('z', 434);
let compareMap = (m1, m2) => (
m1.size === m2.size &&
(new Map([...m1, ...m2])).size === m1.size
)
console.info('Compare A & B: ', compareMap(A, B));
console.info('Compare A & C: ', compareMap(A, C));
console.info('Compare B & C: ', compareMap(B, C));
Если вы не знали: фрагменты кода имеют встроенную кнопку автоформатирования: i.stack.imgur.com/RwGHH.png
Спасибо за редактирование выравнивания. Тем не менее, люди должны сосредоточиться на контенте (по крайней мере, когда он двухстрочный), но да, доза выравнивания имеет значение для лучшей видимости фактического контента!
Вот один лайнер, обернутый функцией TypeScript.
function sameKeys(a: Map<string, string>, b: Map<string, string>): boolean {
return a.size === b.size && [...a.keys()].every(key => b.has(key))
}
Вы имеете в виду stackoverflow.com/questions/14368596/…?