I am trying to make a very simplified version of Twitter aka microblogging site.
It needs to run in memory so no using of databases or networking and all interfacing is to be done in code.
I have a few functions that allow you to create a new user, a new message as a user and a function to get the messages of a user.
AddUser(username)
AddMessage(username, message)
GetMessages(username)
AddFollower(username, nameToFollow)
GetFollowedMessage(username)
Users are able to follow other users which allows them to view the messages of the users they follow.
So far I am currently using a List
to store a User
object which has a username, list of messages, and a list of followers.
public class User
{
public String username;
public List<User> followers;
public List<String> messages;
}
For adding a new message to the users i currently go through a list of all of the users until I find the corresponding username and then add the messages to that user like this:
//Add new message to user
private static void AddMessage(string username, string message)
{
for (int i = 0; i < users.Count; i )
{
if (users[i].username == username)
{
users[i].messages = new List<String>();
users[i].messages.Add(message);
}
}
}
Is there a better way of doing this that doesn't involve having to loop through all of the users?
CodePudding user response:
This is exactly what Dictionaries are for. A username is unique, so it can be used to look up the relevant information about that user.
Starting with just the list of messages for a user:
Dictionary<string, List<string>> userMessages = new();
The Key is the username, and the Value is the list of messages that user has made.
You can retrieve all the messages a user has made with:
List<string> messages = userMessages.GetValueOrDefault("tom") ?? new List<string>();
And you can insert a message with this:
if (userMessages.TryGetValue("tom", out var existingList))
{
existingList.Add("new message");
}
else
{
userMessages["tom"] = new List<string> { "new message" };
}
You can make other dictionaries that sit next to this one, such as one that maps a username to the list of people they follow, and one that maps a username to the list of users who follow them.
So, say you setup the following dictionaries:
Dictionary<string, List<string>> userFollows = new();
Dictionary<string, List<string>> userFollowedBy = new();
The Value would be a list of usernames, not a full "User" object. Remember, you can always use the username to quickly lookup the data you want.
If you ask yourself "How can I get all the messages from people that Tom follows?", you'd do:
IEnumerable<string> EnumUserFollows(string username) =>
userFollows.GetValueOrDefault(username) ?? new List<string>();
IEnumerable<string> EnumUserMessages(string username) =>
userMessages.GetValueOrDefault(username) ?? new List<string>();
List<string> messagesByUsersTomFollows = EnumUserFollows("tom")
.SelectMany(username => EnumUserMessages(username))
.ToList();