Home > Mobile >  How can I prevent looping through all users to find the object I want to modify?
How can I prevent looping through all users to find the object I want to modify?

Time:08-03

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();
  •  Tags:  
  • c#
  • Related