#javascript #arrays #object
#javascript #массивы #объект
Вопрос:
У меня есть два массива объектов, подобных этому:
let data1 = [ { userid_b: 'dan12345' }, { userid_b: 'emma12345' } ]
let data2 =[
{ username: 'dan', userid: 'dan12345' },
{ username: 'johndoe', userid: 'john12345' },
{ username: 'emma', userid: 'emma12345' },
{ username: 'Bob', userid: 'bob12345' },
{ username: 'Sam', userid: 'sam12345' }
]
Я хочу сравнить эти два из userid_b
и userid
, и если они совпадают, я хочу добавить новый атрибут к data2
.
Итак, я хочу, чтобы результат был таким:
let data2 =[
{ username: 'dan', userid: 'dan12345', newAttribute: true },
{ username: 'johndoe', userid: 'john12345' },
{ username: 'emma', userid: 'emma12345', newAttribute: true },
{ username: 'Bob', userid: 'bob12345' },
{ username: 'Sam', userid: 'sam12345' }
]
Как я могу этого добиться?
Ответ №1:
Зациклите оба массива и сравните значения, выполнив присвоение при необходимости:
var data1 = [
{ userid_b: 'dan12345' },
{ userid_b: 'emma12345' }
];
var data2 = [
{ username: 'dan', userid: 'dan12345' },
{ username: 'johndoe', userid: 'john12345' },
{ username: 'emma', userid: 'emma12345' },
{ username: 'Bob', userid: 'bob12345' },
{ username: 'Sam', userid: 'sam12345' }
];
// Loop the main array
for (var i = 0; i < data2.length; i ) {
// Loop the second array
for (var j = 0; j < data1.length; j ) {
// If the user id matches
if (data2[i].userid == data1[j].userid_b) {
// Add the attribute
data2[i].newAttribute = true;
// Break out of the the 'j' loop to stop unnecessary iterations
break;
}
}
}
console.log(data2);
Комментарии:
1. не было бы более эффективным сначала выполнить цикл
data
?2. Да, возможно, вы правы. В любом случае вы заставили меня не забыть добавить разрыв в.
Ответ №2:
Вы можете выполнить обход массива с помощью цикла foreach, см. ниже
var data1 = [ { userid_b: 'dan12345' }, { userid_b: 'emma12345' } ];
var data2 =[
{ username: 'dan', userid: 'dan12345' },
{ username: 'johndoe', userid: 'john12345' },
{ username: 'emma', userid: 'emma12345' },
{ username: 'Bob', userid: 'bob12345' },
{ username: 'Sam', userid: 'sam12345' }
];
data1.forEach(function(data1record,index,data1arr){
data2.forEach(function(data2record,data2idx,data2arr){
if(data1record.userid_b===data2record.userid){
data2record["newAttribute"]=true;
}
})
});
console.log(data2);
Комментарии:
1. Извините, я не понял, не могли бы вы объяснить поподробнее?
2. datarecord2 — это объект, который находился в массиве data2 и имел свойство userid, поэтому ссылался только я. В вопросе задавался вопрос о сравнении на основе идентификатора пользователя..
Ответ №3:
// Make an array of new users for easy lookup.
const newUsers = data1.map(elt => elt.userid_b);
// Filter data2 down to only matching elements, then add new attribute.
data2.filter(elt => newUsers.contains(elt.username))
.forEach(elt => elt.newAttribute = true);
Ответ №4:
Вы также могли бы сделать что-то подобное этому.
let data1 = [{
userid_b: 'dan12345'
}, {
userid_b: 'emma12345'
}]
let data2 = [{
username: 'dan',
userid: 'dan12345'
}, {
username: 'johndoe',
userid: 'john12345'
}, {
username: 'emma',
userid: 'emma12345'
}, {
username: 'Bob',
userid: 'bob12345'
}, {
username: 'Sam',
userid: 'sam12345'
}];
var userIds = data1.map(function(obj) {
return obj.userid_b;
});
var result = data2.map(function(dataObj) {
if (userIds.includes(dataObj.userid)) {
dataObj.newAttribute = true;
}
return dataObj;
});
console.log(result);
Ответ №5:
Преобразуйте data1
в new Map()
, а затем выполняйте итерацию data2
всякий раз, когда userid
находится на карте add newAttribute
prop к объекту:
const data1 = [ { userid_b: 'dan12345' }, { userid_b: 'emma12345' } ]
const data2 =[
{ username: 'dan', userid: 'dan12345' },
{ username: 'johndoe', userid: 'john12345' },
{ username: 'emma', userid: 'emma12345' },
{ username: 'Bob', userid: 'bob12345' },
{ username: 'Sam', userid: 'sam12345' }
];
const usersSet = new Set(data1.map((item) => item.userid_b));
data2.forEach((item) => usersSet.has(item.userid) amp;amp; (item.newAttribute = true));
console.log(data2);
Комментарии:
1. Почему вы используете
Map
вместоSet
?2. Я привык создавать карты объектов, поэтому, естественно, выбираю Map, но вы правы, Set было бы лучше в подобных случаях.
Ответ №6:
Возьмите имена пользователей (значения) из объектов первого массива:
var data1_values = data1.map(o => {
return o.userid_b;
});
Результатом является data1_values = ['dan12345', 'emma12345']
.
Теперь пройдемся по объектам data2
с map()
помощью. Проверьте с помощью
data1_values.indexOf(o.userid) > -1
( o
является объектом data2
)
если в нем data1_values
есть o.userid
.
Всего:
let data1 = [
{ userid_b: 'dan12345' },
{ userid_b: 'emma12345' }
];
let data2 = [
{ username: 'dan', userid: 'dan12345' },
{ username: 'johndoe', userid: 'john12345' },
{ username: 'emma', userid: 'emma12345' },
{ username: 'Bob', userid: 'bob12345' },
{ username: 'Sam', userid: 'sam12345' }
];
var data1_values = data1.map(o => {
return o.userid_b;
});
data2.map((o, i) => {
if(data1_values.indexOf(o.userid) > -1) {
data2[i]["newAttribute"] = true;
}
});
console.log(data2);