More Fun With Linq

Say you have a class named BannedProgram and it has a collection of DayOfWeek and a string ProcessName. Now the collection of DayOfWeek is basically a way to set the days of the week it’s banned. With this you want to create a collection of these BannedPrograms, each with their own names and days they are banned. Simple, I know.

Next you have a list of processes that are currently running and you want to get all the processes that match the names in the BannedPrograms list AND if the current day is a banned day.

First you need the day checked function:

private static Func<DayOfWeek, Boolean> dayIsToday =
  currentDay => currentDay == DateTime.Now.DayOfWeek;

Then you need the method to get the banned processes that are currently running:

private static Process[] GetBannedProcesses(BannedProgram[] programs, Process[] processes)
{
  var processList = from process in processes
  where
  (
    from program in programs
    where program.DaysBanned.Any(dayIsToday)
    select program.ProcessName
  ).Contains(process.ProcessName)
  select process;

  return processList.ToArray();
}

What this is doing:

Well if you look at this:

from program in programs
where program.DaysBanned.Any(dayIsToday)
select program.ProcessName

This is going to grab any BannedProgram that has a DayOfWeek that matches today and it will select only it’s name. This will give you a list of names of the BannedProcesses that can not be played today.

var processList = from process in processes
where
(
  from program in programs
  where program.DaysBanned.Any(dayIsToday)
  select program.ProcessName
).Contains(process.ProcessName)

This checks to see if any of the currently running processes have a name that matches a name in the banned program list.

And now you have a list of processes to kill. Yay. Not sure this is a big deal, just thought it was a fun example of using linq and subselects.

USING???

using System;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Windows.Forms;

More Useless info

Just in case you wanted to create something to kill a process, I have this little bit:

using System;
using System.Diagnostics;

Action<Process> killProcess = currentProcess => currentProcess.Kill();
Process[] processes;
String processToKill;

processToKill = "WAR";
processes = Process.GetProcesses();

processes.Select(currentProcess => currentProcess.ProcessName == processToKill)
.ToList()
.ForEach(killProcess);

I originally intended this as a service that would kill processes that were running on a specific day. IE To stop myself from playing games during the week. Problem was finding a way to stop me from killing the service. Now you can set a service to disallowing stopping it. The idea being that I would have another program that would stop it only if a password was enter correctly. (A certain woman would have this password) Trouble is, I can just open up the task manager and kill the process. Now I have to rely on self control. WHICH IS THE REASON WHY I WANTED THIS IN THE FIRST PLACE.

Combine Lambda Expressions: The And and the Or

Found this post here but wanted to make a really simple example to demonstrate this.

The idea is simple, take something like this:

currentItem => currentItem.BooleanMethodOne() && currentItem.BooleanMethodTwo()

but say you only want to have one clause or both. Well you could make three separate expressions, but what if you wanted to add even more later? What if you wanted to mix and match? What if you’re reading thing because you watched to see what page could possibly be on the last page of a google search? Well I have answers… stolen answers.

First the needed And and Or methods:

public static Expression<Func<T, Boolean>> And<T>(
   Expression<Func<T, Boolean>> expressionOne,
    Expression<Func<T, Boolean>> expressionTwo
)
{
  //Basically this is like a bridge between the two expressions.  It will take the T
  //parameter from expressionOne and apply it to expression two. So if 
  // oneItem => oneItem.OneMethod() is expressionOne
  // twoItem => twoItem.TwoMethod() is expressionTwo
  //it would be like replacing the twoItem with the oneItem so that they now point
  //to the same thing.
  var invokedSecond = Expression.Invoke(expressionTwo, expressionOne.Parameters.Cast<Expression>());

  //Now this is to create the needed expresions to return.  It will take both early expressions
  //and use the item from the first expression in both.
                    
  //It will look something like this:
  //currentItem => (currentItem.OneMethod And Invoke(currentItem => currentItem.TwoMethod()))
  //As you can see, it looks to be running expressionOne and then a new method that basically
  //calls expressionTwo with the same value (currentItem)
  return Expression.Lambda<Func<T, Boolean>>(
   Expression.And(expressionOne.Body, invokedSecond), expressionOne.Parameters
  );
}

public static Expression<Func<T, Boolean>> Or<T>(
Expression<Func<T, Boolean>> expressionOne, 
Expression<Func<T, Boolean>> expressionTwo
)
{
  var invokedSecond = Expression.Invoke(expressionTwo, expressionOne.Parameters.Cast<Expression>());

  return Expression.Lambda<Func<T, Boolean>>(
   Expression.Or(expressionOne.Body, invokedSecond), expressionOne.Parameters
  );
}

And here’s a test for it:

String[] list;

list = new String[] { "a", "b", "c", "ac", "ab", "cc", "d", "dd", "dc" };

Expression<Func<String, Boolean>> stringLikeA = currentString => currentString.Contains("a");
Expression<Func<String, Boolean>> stringLikeB = currentString => currentString.Contains("b");
Expression<Func<String, Boolean>> stringLikeC = currentString => currentString.Contains("c");

Expression<Func<String, Boolean>> neededUser = And<String>(stringLikeA, stringLikeB);
list.Where(neededUser.Compile());

//a
Assert.IsTrue(list.Where(neededUser.Compile()).Count() == 1);  //ab

//a, c, ac, ab, cc, dc
neededUser = Or<String>(stringLikeA, stringLikeC);

Assert.IsTrue(list.Where(neededUser.Compile()).Count() == 6);

//ab, c, ac, cc, dc
neededUser = And<String>(stringLikeA, stringLikeB);
neededUser = Or<String>(neededUser, stringLikeC);
Assert.IsTrue(list.Where(neededUser.Compile()).Count() == 5);

USINGS!!ONEONE

using System;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Solve FizzBuzz Using Linq Extension Methods

So if you haven’t heard of the FizzBuzz test, it’s basically taking in a list of numbers and figuring out if they are divisible, cleanly, by two numbers. Say you have 3 and 5 and this is your list:

1

3

5

10

15

If the number is divisible by 3, then return the Fizz string. If the number is divisible by 5, return a Buzz string. If it’s divisible by both, then return FizzBuzz.

1

Fizz

Buzz

Buzz

FizzBuzz

Pretty simple and in actuality pretty easy to do with old C# tools, but I wanted to do this with Linq. With the use of Funcs, Actions, and Linq extension methods it can be done fairly easily. Technically you can do the whole thing in one line if you don’t want to bother with refactoring.

I have no idea how to format this cleanly, so sorry if the format is confusing. Basically it is take a list, get the ones you want, concatenate it with the next list.

public static IList<KeyValuePair<Int32, String>> ConvertListOfIntegersWithLinqMethods(IList<Int32> listToConvert, Int32 fizzNumber, Int32 buzzNumber)
{
var result =
  listToConvert
    .Where(WhereBothDivisible(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("FizzBuzz"))
    .Concat(
  listToConvert
    .Where(WhereBuzzDivisable(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("Buzz")))
    .Concat(
  listToConvert
    .Where(WhereFizzDivisable(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("Fizz")))
    .Concat(
  listToConvert
    .Where(WhereNeitherDivisable(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("Nothing")));

 return result.ToList().OrderBy(currentItem => currentItem.Key).ToList();
}

Using these:

private static Func<Int32, KeyValuePair<Int32, String>> selectKeyValuePair(String value)
{
 return currentItem => new KeyValuePair<Int32, String>(currentItem, value);
}

private static Func<Int32, Boolean> WhereBothDivisible(Int32 fizzNumber, Int32 buzzNumber)
{
 return  currentItem => IsDivisible(currentItem, fizzNumber) && IsDivisible(currentItem, buzzNumber);
}

private static Func<Int32, Boolean> WhereFizzDivisable(Int32 fizzNumber, Int32 buzzNumber)
{
 return currentItem => IsDivisible(currentItem, fizzNumber) && !IsDivisible(currentItem, buzzNumber);
}

private static Func<Int32, Boolean> WhereBuzzDivisable(Int32 fizzNumber, Int32 buzzNumber)
{
 return currentItem => !IsDivisible(currentItem, fizzNumber) && IsDivisible(currentItem, buzzNumber);
}

 private static Func<Int32, Boolean> WhereNeitherDivisable(Int32 fizzNumber, Int32 buzzNumber)
{
 return currentItem => !IsDivisible(currentItem, fizzNumber) && !IsDivisible(currentItem, buzzNumber);
}

Beyond the wall

So I never gave a solution to this problem and thought I might do that real fast.

If you recall, this was the main sticking point of creating a Func for a select clause:

Func<User, EHH??> selectUserID = currentUser =>  new { currentUser.ID, currentUser.UserName };

Well there is no one solution to this, but there is an easy and clean solution:

 public class UserQueryItem
 {
   public UserQueryItem ( Int32 userID, String userName )
   {
      UserID = userID;
      UserName = userName;
   }

   public Int32 UserID { get; set; }
   public String UserName { get; set; }
 }

Create a class to hold the information.

 Func<User, UserQueryItem> selectUserID = currentUser =>  new UserQueryItem { UserID = currentUser.ID, UserName = currentUser.UserName };

Or

 Func<User, UserQueryItem> selectUserID = currentUser =>  new UserQueryItem (currentUser.ID, currentUser.UserName);

Pretty simple, just a little more work.