I get a response from backend which is an array of object which is as below mentioned
[{"userID":1,"firstName":"George","lastName":"Russell","addressID":"1","address_value":"27 London Street E146AA","expDate":"2022-12-12T17:09:37.000Z"},{"userID":1,"firstName":"George","lastName":"Russell","phoneId":"1","phone_value":"97627445368"},{"userID":2,"firstName":"George","lastName":"Russell","phoneId":"2","phone_value":"07884076692"},{"userID":1,"firstName":"George","lastName":"Russell","emailId":"1","email_value":"georgerussell#outlook.com"},{"userID":1,"firstName":"George","lastName":"Russell","employerId":"1","employer_value":"QMUL"},{"userID":28,"firstName":"Binny","lastName":"Bansal","employerId":"2","employer_value":"Google Inc"},{"userID":1,"firstName":"George","lastName":"Russell","nationalityId":"1","nationality":"Indian"},{"userID":1,"firstName":"George","lastName":"Russell","passportId":"1","passportNumber":"123445567"}]
I am trying to get all the details of users from the backend which are stored in different tables like a separate table for Phone, Address, Email etc. And similarly for EmailShared or PhoneShared which contains the information regarding with which organisation has the information has been shared. As we can see that HSBC has the address of George.
But what I want to try and do is that have all the information in a single object instead of a different one for each attribute(address, phone, email).
What right now we have is the below one
[
{
addressID: "1"
address_value: "27 London Street E146AA"
expDate: "2022-12-12T17:09:37.000Z"
firstName: "George"
lastName: "Russel"
userID: 1
},
{
firstName: "George"
lastName: "Russel"
phoneId: "1"
phone_value: "97627445368"
userID: 1
}
]
What I am trying to achieve is something which has phone number and address as an example but would love to have all the attributes(phone, email, passport, employer, address etc) .
{
addressID: "1"
address_value: "27 London Street E146AA"
expDate: "2022-12-12T17:09:37.000Z"
firstName: "George"
lastName: "Russel"
userID: 1
phoneId: "1"
phone_value: "97627445368"
emailId:"1",
email_value:"georgerussell#outlook.com"
employerId:"1"
employer_value:"QMUL"
nationalityId:"1"
nationality:"Indian"
passportId:"1"
passportNumber:"123445567"
},
I was trying to do it with the following code as we have the userId as unique property and based on that I was trying to have the desired output but I cannot understand what am I missing in here.
result = data.reduce(function (r, a) {
r[a.userID] = r[a.userID] || [];
r[a.userID].push(a);
return r;
}, Object.create(null));
console.log(result);
const finalResult = [];
Object.keys(result).forEach(el => {
result[el].forEach(el1 => {
console.log(el1)
//finalResult.push(...el1)
})
})
You were on the right track, just needs little improvement like using Object.values() instead of Object.keys(); and I used logical nullish assignment (??=)
const data = [{"userID":1,"firstName":"George","lastName":"Russell","addressID":"1","address_value":"27 London Street E146AA","expDate":"2022-12-12T17:09:37.000Z"},{"userID":1,"firstName":"George","lastName":"Russell","phoneId":"1","phone_value":"97627445368"},{"userID":2,"firstName":"George","lastName":"Russell","phoneId":"2","phone_value":"07884076692"},{"userID":1,"firstName":"George","lastName":"Russell","emailId":"1","email_value":"georgerussell#outlook.com"},{"userID":1,"firstName":"George","lastName":"Russell","employerId":"1","employer_value":"QMUL"},{"userID":28,"firstName":"Binny","lastName":"Bansal","employerId":"2","employer_value":"Google Inc"},{"userID":1,"firstName":"George","lastName":"Russell","nationalityId":"1","nationality":"Indian"},{"userID":1,"firstName":"George","lastName":"Russell","passportId":"1","passportNumber":"123445567"}];
const result = data.reduce(function(r, a) {
r[a.userID] ??= []; // it's the same as r[a.userID] = r[a.userID] || [];
r[a.userID].push({ ...a
});
return r;
}, {}); //Object.create(null)
let finalResult = [];
Object.values(result).forEach((arrObj) => {
let result = {};
Object.values(arrObj).forEach((obj) => {
Object.assign(result, obj);
});
finalResult.push(result);
});
console.log(finalResult);
For this type of problem, I would go with changing how the backend service operates; where it should doing a JOIN on the multiple tables so that you only get one object for each user, instead multiple.
That being said, I would accomplish this easiest with a map.
const result = [{"userID":1,"firstName":"George","lastName":"Russell","addressID":"1","address_value":"27 London Street E146AA","expDate":"2022-12-12T17:09:37.000Z"},{"userID":1,"firstName":"George","lastName":"Russell","phoneId":"1","phone_value":"97627445368"},{"userID":2,"firstName":"George","lastName":"Russell","phoneId":"2","phone_value":"07884076692"},{"userID":1,"firstName":"George","lastName":"Russell","emailId":"1","email_value":"georgerussell#outlook.com"},{"userID":1,"firstName":"George","lastName":"Russell","employerId":"1","employer_value":"QMUL"},{"userID":28,"firstName":"Binny","lastName":"Bansal","employerId":"2","employer_value":"Google Inc"},{"userID":1,"firstName":"George","lastName":"Russell","nationalityId":"1","nationality":"Indian"},{"userID":1,"firstName":"George","lastName":"Russell","passportId":"1","passportNumber":"123445567"}];
const newUserMap = new Map();
result.forEach((user) => {
const { userID } = user;
if (newUserMap.has(userID)) {
const existingUser = newUserMap.get(userID);
newUserMap.set(userID, {...existingUser, ...user});
} else {
newUserMap.set(userID, user);
}
});
console.log(newUserMap);
Where the keys are the user ids and the values within them are the user objects. You are also able to run through each entry with a .forEach() loop; just like an array.
If you want to keep them as an array of objects, then you could accomplish this with something similar to a map, but it is quite costly in performance due to the .findIndex():
const result = [{"userID":1,"firstName":"George","lastName":"Russell","addressID":"1","address_value":"27 London Street E146AA","expDate":"2022-12-12T17:09:37.000Z"},{"userID":1,"firstName":"George","lastName":"Russell","phoneId":"1","phone_value":"97627445368"},{"userID":2,"firstName":"George","lastName":"Russell","phoneId":"2","phone_value":"07884076692"},{"userID":1,"firstName":"George","lastName":"Russell","emailId":"1","email_value":"georgerussell#outlook.com"},{"userID":1,"firstName":"George","lastName":"Russell","employerId":"1","employer_value":"QMUL"},{"userID":28,"firstName":"Binny","lastName":"Bansal","employerId":"2","employer_value":"Google Inc"},{"userID":1,"firstName":"George","lastName":"Russell","nationalityId":"1","nationality":"Indian"},{"userID":1,"firstName":"George","lastName":"Russell","passportId":"1","passportNumber":"123445567"}];
const newUserArray = [];
result.forEach((user) => {
const { userID } = user;
const existingUserIndex = newUserArray.findIndex(newUser => newUser.userID === userID);
if (existingUserIndex !== -1) {
newUserArray[existingUserIndex] = Object.assign(newUserArray[existingUserIndex], user);
} else {
newUserArray.push(user);
}
});
console.log(newUserArray);
Please see my code below.
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}
addUser() {
users.push(this.name, this.email)
}
}
const userOne = new User ('John', 'john#mail.com');
const userTwo = new User ("Alan", "alan#mail.com");
let users = [];
userOne.addUser();
userTwo.addUser();
After method addUser i have array with names and emails but i would like to have an array with objects as below
users = [
{ name: 'John', email: 'john#mail.com' }
{ name: 'Alan', email: 'alan#mail.com' }
]
How my method addUser should looks in my prototype and if variable users is in correct place or can be store somewhere in Class?
Thanks in advance
You're pushing the object properties one after the other, rather than as an object together.
Try this for your addUser method:
addUser() {
users.push({name: this.name, email: this.email})
}
You just need to push each proprieties
users.push({name: this.name, email: this.email})
If you want to do this automatically you can use:
users.push(Object.assign({}, this))
Or you cloud just pass the whole object:
users.push(this)
Anyhow, I would suggest not to use users globally.
Hello Everyone I am having some problems trying to make a function. As shown in the code. I want to make the interestMatch function. What the function needs to do is to look at all the Users and find those users that have the same interest - bob and jack in my code. I think it should be something with an if statement. Kinda: "if any users have the same interest" "return this user and this user is a match!"
Can someone help me!?
Thanks a lot!
class User {
constructor(username, password, firstname, lastname, email, birthday, gender, interest){
this.username = username;
this.password = password;
this.firstname = firstname;
this.lastname = lastname;
this.email = email;
this.birthday = birthday;
this.gender = gender;
this.interest = interest
}
}
let InterrestArray = ["Netflix", "Sports", "Party", "Business", "Children", "Hygge"]
let bob = new User ("bob123", "12345", "Bob", "bobiski", "bob#bob.com", "2000-10-10", "male", interrest[0]);
let jack = new User ("jack20", "340302", "Jack", "jackiski", "jack#jack.com", "2000-06-10", "male", interrest[0]);
let thif = new User ("thif20", "204903", "Thifanny", "Thifiski", "thif#jack.com", "2000-09-12", "famale", interrest[1]);
function interestMatch(){
???
}
console.log(interestMatch())
// I want it to console.log - "bob maches with jack!" - because the have the same interrest
```
A very simple approach would be to have two nested for loops which iterate over the users and compares their interest:
function interestMatch(users){
for (let i = 0; i < users.length; i++) {
const user1 = users[i];
// No need to iterate over any user that comes "before" user1.
for (let j = i+1; j < users.length; j++) {
const user2 = users[j];
if (user1.interest === user2.interest) {
return `${user1.username} matches with ${user2.username}`;
}
}
}
}
Of course things get more complex if users can have multiple interests or if you want to return all matches. In that case it might make sense to create an interest -> list of users map.
Any approach the OP is looking for is a little bit more complex than
it should be something with an if statement.
A valid approach was to scan through a list of users, look up each of a user's interest and push the user into its interest related array. Thus the base approach creates an interest based map or index with interest-specific user-lists.
This was just the first part, providing an approach that creates a data structure which can be processed further.
With the needed data structure at hand (a key value store, where interest is key and a specific user-list is each key's value) one approaches the second part which is about output/rendering.
For each key-value pair (interest and user list) one does invoke a user list specific render function. Within this step one also does map the user list into a list of e.g. each of a user's first name.
The final render function then needs to take care of the edge cases ... like ... there is a single user, with an interest which is not shared by anyone else ... or ... there are more than two users who have one and the same interest in common ...
class User {
constructor(
username, password, firstname, lastname,
email, birthday, gender, interest
) {
Object.assign(this, {
username, password, firstname, lastname,
email, birthday, gender, interest
});
}
}
function groupUserByInterest(index, user) {
const { interest } = user;
const sameInterestList = index[interest] || (index[interest] = []);
sameInterestList.push(user);
return index;
}
const interestList = ["Netflix", "Sports", "Party", "Business", "Children", "Hygge"];
const userList = [
new User ("bob123", "12345", "Bob", "bobiski", "bob#bob.com", "2000-10-10", "male", interestList[0]),
new User ("jack20", "340302", "Jack", "jackiski", "jack#jack.com", "2000-06-10", "male", interestList[0]),
new User ("jane20", "340303", "Jane", "janinski", "jane#jane.com", "2000-06-10", "famale", interestList[0]),
new User ("thif20", "204903", "Thifanny", "Thifiski", "thif#jack.com", "2000-09-12", "famale", interestList[1])
];
// const [ bob, jack, jane, thif ] = userList;
function renderUsersOfSameInterest(interest, userList) {
const [ first, ...rest ] = userList;
let template;
if (!rest.length) {
template = `There is no other user who matches ${ first }'s interest (${ interest }).`;
} else {
template = `${ first }'s interest (${ interest }) maches with the one of ${ rest.join(' and ') }!`;
}
console.log(template);
}
function renderUsersOfSameInterestsByFirstname(index) {
Object.entries(index).forEach(([interest, userList]) =>
renderUsersOfSameInterest(interest, userList.map(user =>
user.firstname))
);
// console.log('index', index);
}
renderUsersOfSameInterestsByFirstname(
userList.reduce(groupUserByInterest, {})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
I'm trying to write on Firebase an object with this structure and when a user reloads or leaves page, the user's data will be removed from Firebase.
/users {
1: {name: name, win: win},
2: {name: name, win: win}
}
This code does that but generates random Id each push so I cannot interfere with each user's data later:
var database = firebase.database();
var userRef = database.ref("/users");
function createNewUser() {
var newUser = $('#newUser').val().trim();
if (newUser) {
var con = userRef.push({
name: newUser,
win: 0,
loss: 0
});
con.onDisconnect().remove();
}
else {
return;
}
}
$('#startButton').on('click', createNewUser);
This code is similar but has error:
onDisconnect is not a function
function createNewUser() {
var newUser = $('#newUser').val().trim();
if (newUser) {
var con = database.ref('users/ + 1).set({
name: newUser,
win: 0,
loss: 0
});
con.onDisconnect().remove();
}
else {
return;
}
}
If I use push, I can retrieve each user's ID but I still won't be able to change user's data, especially if 1 of the 2 users leaves.
When using .push, Firebase will always generate a random key for this new entry.
You can use .set instead of .push and you'll need to add to the path/ref a unique identifier for each user, like userName or userId as userRef.child('/userid').set
Or you can capture the new entry after creation, and get the new generated random key, and then use it for the .remove
See Firebase Documentation here
Hope that helps.
All the best.