1

I have a log which has information such as:

Jane opened the video file at 9/10/2015 7:30 AM

Bob opened the video file at 9/11/2015 7:38 AM

Dave opened the video file at 9/12/2015 10:30 AM

I'm looking to filter this text file to only the current date and users who have opened the video file show, and create a new string like so:

Dave opened the video file at 9/12/2015 10:30 AM

Then, compare this to a list of users to see who hasn't who opened the file today, so I would get notified that Jane and Bob haven't opened the file yet today.

Here's what I've tried:

    private void refreshbtn_Click(object sender, EventArgs e)
    {
        string currentdate = DateTime.Now.ToShortDateString();
        string[] logfile = File.ReadAllLines(@"C:\log.txt");
        string[] users = {"Jane", "Bob", "Dave"};

        if (!logfile.Contains(currentdate))
        {
            logfile.Where(val => val != currentdate).ToArray();

            if (logfile.Contains(users.ToString()))
            {
                string x = users.ToString();
                richTextBox1.Text = x;

            }
        }
    }

Is anyone able to spot where I'm going wrong and/or explain to me what would be the correct process?

EyeSeeSharp
  • 604
  • 1
  • 8
  • 21

3 Answers3

2

The problem is that .Contains is operating on an array, not a String. .Contains on an array will only match entire array elements.

Example, logfile.Contains("Dave opened the video file at 9/12/2015 10:30 AM") would be true, but logfile.Contains("Dave") is false.

You could try something like this (untested):

String[] watchers = logfile.where(s => s.Contains(currentdate) && users.Any(s.Contains))).toArray();

(Full props to this answer, I had to quickly double-check how to look for a subset of this element within another array)

Community
  • 1
  • 1
Ian
  • 1,475
  • 2
  • 15
  • 31
2

There's a couple of things that I notice.

  • This call, logfile.Where(val => val != currentdate).ToArray() doesn't have it's results used. Where() returns a new sequence based on the predicate, not mutating the existing sequence.
  • logfile.Contains(currentdate) is checking if or not any of the strings in logfile equal the currentdate string. Based upon the format you've provided, no is a safe answer. This Contains() call is oerating on the logfile array, not each string. You probably want logfile.Any(line => line.Contains(currentdate)), which will check if any of the strings contain the currentdate string. This may be a little confusing - but note that the Contains() called on line is the string.Contains() method, not the Enumerable extension method.

Here's a snippet which you can likely adapt to your program,

var currentDate = DateTime.Now.ToShortDateString();
var logFile = File.ReadAllLines(@"log.txt");
var users = new [] { "Jane", "Bob", "Dave" };

var viewers = from line in logFile
                    where line.Contains(currentDate)
                    select users.First(user => line.Contains(user));

var transgressers = users.Except(viewers);
foreach (var user in transgressers)
{
    Console.WriteLine(user);
}

If this is a one-off case this may very well be fine, but if you've got other users of this log file(s), I'd recommend parsing the entries into objects so you can make more meaningful code.

Given these two types:

class User
{
    public string Name { get; }
}

class UserView
{
    public User Viewer { get; }
    public DateTime ViewTime {get; }
}

and an IEnumerable of each, you could shorten this to:

var nonViews = users.Except(
                views.Where(v => v.ViewTime.Date == DateTime.Today)
                     .Select(v => v.Viewer));
jdphenix
  • 15,022
  • 3
  • 41
  • 74
0

You did not tell us what you are getting, but:

  • The condition in line 7 is clearly reversed.
  • You are not doing anything with the result of ToArray() in line 9
  • users.ToString() is totally meaningless (what are you expecting to get there?)

I suggest that you open the debugger and start looking at what your program is doing step by step.

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154