Reputation: 1276
I have 2 lists of strings in C# showing the players who have joined and left a particular game. I'm trying to attempt to determine who is still in the game by matching both lists and eliminating the entries of those who have left the game. Please suggest a easy and pain free algorithm to go about doing this. My current code is as follows
string input = inputTextBox.Text;
string[] lines = input.Split(new string[] {"\r\n", "\n"}, StringSplitOptions.None);
List<string> filteredinput = new List<string>();
List<string> joinedlog = new List<string>();
List<string> leftlog = new List<string>();
for (int i = 0; i<lines.Length; i++)
{
if (lines[i].Contains("your game!"))
filteredinput.Add(lines[i]);
}
for (int i =0; i<filteredinput.Count; i++)
{
if (filteredinput[i].Contains("joined"))
joinedlog.Add(filteredinput[i]);
else if (filteredinput[i].Contains("left"))
leftlog.Add(filteredinput[i]);
}
Here is some sample input :
{SheIsSoScrewed}[Ping:|] has joined your game!.
{AngeLa_Yoyo}[Ping:X] has joined your game!.
{SheIsSoScrewed} has left your game!(4).
Upvotes: 0
Views: 7975
Reputation: 89171
string input = inputTextBox.Text;
string[] lines = input.Split(new string[] {"\r\n", "\n"}, StringSplitOptions.None);
Regex joinedLeft = new Regex(@"\{([^{}]*)}.*? has (joined|left) your game!");
HashSet<string> inGame = new HashSet<string>();
foreach (string line in lines)
{
Match match = joinedLeft.Match(line);
if (!match.Success)
continue;
string name = match.Groups[1].Value;
string inOrOut = match.Groups[2].Value;
if (inOrOut == "joined")
inGame.Add(name);
else
inGame.Remove(name);
}
Upvotes: 0
Reputation: 53396
Are you asking how to get your two lists, or how to find the current players after you've already got the two lists?
The second part can be done with Linq....
List<string> joinedGame;
List<string> leftGame;
List<string> currentInGame
= joinedGame.Where(x => !leftGame.Contains(x)).ToList();
EDIT In response to your comment, having read your question again then obviously the above won't work because you are building your lists in a weird way.
You are storing the whole string in the list, e.g. user_1 has left the game
, what you should probably be doing is just storing the user name. If you correct this then the above code does exactly what you want.
A full example:
var input = new List<string>()
{
"user_1 has joined the game",
"user_2 has joined the game",
"user_1 has left the game",
"user_3 has joined the game"
};
var joined = new List<string>();
var left = new List<string>();
foreach(string s in input)
{
var idx = s.IndexOf(" has joined the game");
if (idx > -1)
{
joined.Add(s.Substring(0, idx));
continue;
}
idx = s.IndexOf(" has left the game");
if (idx > -1)
{
left.Add(s.Substring(0, idx));
}
}
var current = joined.Where(x => !left.Contains(x)).ToList();
foreach(string user in current)
{
Console.WriteLine(user + " is still in the game");
}
Upvotes: 2
Reputation: 19020
First you need to extract the player names so you can calculate the difference:
var join=new Regex("{(.*)}[.*joined.*?your game");
var joinedNames = filteredinput.Select(l => join.Match(l)).Where(m => m.Success).Select(m => m.Groups[1]).Distinct();
var left=new Regex("{(.*)}[.*left.*?your game");
var leftNames = filteredinput.Select(l => left.Match(l)).Where(m => m.Success).Select(m => m.Groups[1]).Distinct();
Now calculate the difference:
var playersStillInGame = joinedNames.Except(leftNames);
Upvotes: 0
Reputation: 20764
use linq and regex:
var join=new Regex("joined.*?your game");
var joinLog = (from l in lines where join.IsMatch(join) select l).ToList();
var left=new Regex("left.*?your game");
var leftLog = (from l in lines where left.IsMatch(join) select l).ToList();
Upvotes: 0