У меня есть объект:
myObj = {
attendent-0-id:"123",
attendent-0-name:"Bob Smith",
attendent-1-id:"1234",
attendent-1-name:"Alex Smith",
attendent-2-id:"123",
attendent-2-name:"Charlie Smith",
attendent-maxGuest:1,
attendent-party-name:"",
}
Мне нужно создать цикл, который проходит через myObj
и найти все id, а затем сравнивает их для дубликатов. Таким образом, в этом случае он регистрирует ошибку, потому что attendent-0-id
равен attendent-2-id
.
Если я найду дубликаты, мне нужно установить флаг в true;
Я пробовал кучу вещей, и я просто застрял на этом. Спасибо за любую помощь.
В вашем случае вы можете пройти через myObj
с помощью Object.keys() через:
for (const key of Object.keys(obj))
используйте обычный объект в качестве карты для хранения предыдущих значений идентификаторов:
const map = {};
используйте шаблон регулярного выражения, чтобы убедиться, что только определенные идентификаторы оцениваются:
const pattern = /^attendent-\d+-id$/;
а затем с помощью map
запишите ошибку для дубликатов идентификаторов:
if (value in map) {
console.error('${map[value]} is equal to ${key}, which is ${value}');
}
const myObj = {
'attendent-0-id': "123",
'attendent-0-name': "Bob Smith",
'attendent-1-id': "1234",
'attendent-1-name': "Alex Smith",
'attendent-2-id': "123",
'attendent-2-name': "Charlie Smith",
'attendent-maxGuest': 1,
'attendent-party-name': "",
};
function errorOnDuplicateIds(obj) {
const map = {};
const pattern = /^attendent-\d+-id$/;
for (const key of Object.keys(obj)) {
if (pattern.test(key)) {
const value = obj[key]
if (value in map) {
console.error('${map[value]} is equal to ${key}, which is ${value}');
} else {
map[value] = key
}
}
}
}
errorOnDuplicateIds(myObj);
const ids = []; // keep track of found ids
Object.keys(myObj).forEach(key => { // iterate over all properties of myObj
// check if property name is in format "attendent-" *some number* "-id"
if (/^attendent-\d+-id$/.test(key)) {
// check if the id has already been found
if (ids.findIndex(id => id === myObj[key]) !== -1) {
console.log('error');
} else {
ids.push(myObj[key]);
}
}
});
Object.values(myObj)
создаст массив всех значений, а затем вы сможете использовать любой способ найти повторяющиеся элементы в этом массиве.
var myValues = Object.values(myObj); //This will create an array of all values
var uniq = myValues.map((val) => {
return {count: 1, val: val}
}).reduce((a, b) => {
a[b.val] = (a[b.val] || 0) + b.count
return a
}, {});
var duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1)
if (duplicates.length) {
return true;
} else {
return false;
}
Моим первым советом было бы переопределить ваш объект на нечто более гибкое.
let myObject = {
attendants : [
{
id: "123",
name: "Bob Smith"
},
{
id: "456",
name: "Alex Smith"
},
{
id: "768",
name: "Charlie Smith"
},
],
maxGuest: 1,
partyName: ""
};
Это позволит вам выполнять итерацию обслуживающего персонала.
for (var attendant in myObject.attendants){
doSomething(attendant.id, attendant.name);
}
Вы также можете сортировать оператора:
// Sort by id
myObject.attendants.sort(function(left, right){
return left.value - right.value;
});
// Sort by name
myObject.attendants.sort(function (left, right){
var leftName = left.name.toLowerCase();
var rightName = right.name.toLowerCase();
if (leftName < rightName) return -1;
if (leftName > rightName) return 1;
return 0;
});
Теперь давайте предположим, что у вас нет выбора. Тогда это усложняется.
Вам необходимо создать (или изменить существующий) алгоритм сортировки, чтобы он мог использовать ключи, которые генерируются как:
myObject['attendent-${index}-id']
myObject['attendent-${index}-name']
и сохранить пару
Для этого вы можете использовать Object.entries
и Map
(с ключом по значению):
var myObj = {"attendent-0-id":"123","attendent-0-name":"Bob Smith","attendent-1-id":"1234","attendent-1-name":"Alex Smith","attendent-2-id":"123","attendent-2-name":"Charlie Smith","attendent-maxGuest":1, "attendent-party-name":""};
var dupes = [...Object.entries(myObj).reduce(
(map, [key,val]) => map.set(val, (map.get(val) || []).concat(key)),
new Map
).values()].filter(keys => keys.length > 1);
console.log(dupes);
Это решение не дает никакого особого значения формату ключей.
Сказав это, ваша структура объектов выглядит подозрительно плохой дизайн: у вас не должно быть перечислений в ваших объектных ключах. Для этого вы должны использовать массивы.