Friday, August 22, 2008

Speaking of Select

So like Where and other fine Extension methods, Select allows you to either give it a lambda expression like so:
  List<String> newList = userList.Select(user => user.Name);
Or
  List<Int32> newList = userList.Select(user => user.ID);
So either you get a list of Names or IDs. What the hell do you care? Well if you are capable of breathing, you should also notice that one list is a list of strings the other a list of integers. What if you wanted a generic select method? Well for starters you would do something like this:
public List<String> SelectFromUserList(Func<User, String> selectMethod, List<User> userList)
{
  return userList.Select(selectMethod).ToList();
}
Where the select method for a user name would be something like this:
  List<String> nameList = SelectFromUserList(currentUser => currentUser.UserName, userList);
Sweet... oh wait, that only works if I want a list strings. Great if I wanted LastName, FirstName, ect but sucks if I wanted an integer ID.
  List<String> nameList = SelectFromUserList(currentUser => currentUser.UserID, userList); //BOOM
But wait, you can do that!
public List<K> SelectUserNameList<K>(Func<User, K> selectMethod, List<User> userList)
{
  return userList.Select(selectMethod).ToList();
}
Aw snap, now I can get a list of anything I want, well at least a one type, one dimensional array. By the way, this is the first step in probably a series of posts that will end up with a much cleaner way of doing this.

Linq query versus just a Select

Something I ran into using the Ajax.dll and AjaxMethods (Or basically the idea of being able to call a method from .cs file in javascript) is that when returning a list of Users there was difficulty in serialization. Basically, if you have a list of users that contain a list of roles that contain a list of permissions that contain seven wives with seven children with seven dogs and seven cats... Basically a lot of information. Now lazy loading should take care of this, but lets assume there is no lazy loading.(No idea what would cause that...) Well you have an awful lot to pushout to the front end. Let's just say it can be a little sluggish. Lets assume you are just sending the list out, and you've already done all the querying. You could do:
 return userList;
Which is what I was doing. Kind of slow. You could do:
 var query = from user in userList
             select new
             {
                UserName = user.UserName,
                UserID = user.ID
             };

 return query.ToList();
Nothing wrong with that, just a bit verbose for something so simple. You could do this:
 return userList.Select(currentItem => new { Username = currentItem.UserName, UserID = user.ID });
All in one line. Now I personally like the sql-ish linq expressions, but for this why not fit it into one line?

Union to find if two lists match

So let's say you have two lists you want to compare to see if they hold the same items, but the items are not equal reference. Now, if you are comparing two lists that have unique values to compare, Union is perfect.

List 1 { 1, 2, 3, 4, 5 }
List 2 { 2, 1, 4, 3, 5 }

As you can see, there are no repeated values in these two lists. Easy way to figure out if all the values are the same in the two lists:
  var query = (from first in firstList
            select first).Union(from second in secondlist
                                select second);

  Assert.IsTrue(query.Count() == first.Count());
Why does this work? Union combine the two lists, removing any duplicates. So if everything goes correctly, the count of the new list has to match the count of either of the olds lists. After all 5 pairs of duplicate items gets reduced to a list of 5. Now, if there is anything different between the lists the count will get screwed. Why? Because even one difference will cause an extra item to show up in the list.

List 1 { 1, 2, 3, 4, 5 }
List 2 { 1, 2, 3, 4, 6 }
Union { 1, 2, 3, 4 , 5, 6 }

And it will only get worse for every mismatch.

Real worldish example:
    var query = (from user in userListFirst
              select user.UserID).Union(from secondUser in userListSecond
                                       select second.UserID);

    Assert.IsTrue(query.Count() == userListFirst.Count());
Bonus points if you can figure out why this would fail at times. Actually, I already told you...

UsInGS
  using System;
  using System.Linq;

Tuesday, August 19, 2008

Life is fun when you are slow

public void IfTrueRunMethod(Func<Boolean> trueMethod, Action action)
{
  if(trueMethod())
  {
    action();
  }
}
Just something I made for the hell of it to remove:
if(someClass != null && someClass.Property == "hi")
{
  SomeMethod();
}
This can be reduced to one line... yay!
IfTrueRunMethod(() => { someClass != null && someClass.Property == "hi" }, () => SomeMethod());
You could even transform the first part into a method if you want:
IfTrueRunMethod(() => TrueMethod(someClass), () => SomeMethod());
Weeeee!
using System;
using System.Linq;

Thursday, August 14, 2008

Another silly method just for you

So what if you want the names and values from an Enum, but wanted them in dictionary form. Well shoot, a little bit of linq and little bit of that and you got this:
public static IDictionary<String, Int32> ConvertEnumToDictionary<K>()
{
 if (typeof(K).BaseType != typeof(Enum))
 {
   throw new InvalidCastException();
 }

 return Enum.GetValues(typeof(K)).Cast<Int32>().ToDictionary(currentItem => Enum.GetName(typeof(K), currentItem));
}
As you might see, pretty simple. Ok so ToDictionary is kind of odd looking maybe, but really isn't that big of a deal. Basically it assumes the items in the list are the value, but you need to tell it what the key is. In this case, the int values for the enum are the value for the dictionary where the name that matches said int value will become the key for the dictionary. So basically, get the values for the enum. Turn that into an IEnumerable list of Int32, create a Dictionary from that. USINGS!!111
 using System;
 using System.Collections.Generic;
 using System.Linq;

Tuesday, August 12, 2008

You can do that in Javascript? Part 2

Creating divs on the fly and assigning methods: As I have been working with Script Controls lately, I've been forces to learn more about javascript.... yeah I know, bleh. However, in my learnin' I've actually been forced to like Javascript.... yeah I know, bleh. Well one this I was doing was tranfering a front end control to a Script Control. Basically I am building an Auto Complete control that is using the Ajax.dll AjaxMethod stuff. Thus skipping the need for web services that the Ajax Control AutoComplete needs. Anyhow, the reason I am saying this is that it gets a list of Users and dynamically creates a list of divs that change color when hovered over and fill in a textbox when selected. Originally I was doing this by creating the html needed, then appending the innerHTML property on the container div.
function buildSelectableDiv(currentCount, innerText, textboxName, parentDiv)
{
   var defaultClass;
   var divChild;
   var divToAdd;
   var picker;

   //create the parent div
   divToAdd = document.createElement('div');
   //set the id of the div
   divToAdd.setAttribute('name', 'divNames' + currentCount);

   //Create child div
   divChild = document.createElement('div');
   //getting the child ready
   divChild.setAttribute('name', 'divNamesChild' + currentCount);

   //Add child to new parent
   divToAdd.appendChild(divChild);

   return divToAdd;
}
And there you go. Creating a div and adding div to it.

You can do that in Javascript?

So found out yesterday that anonymous methods exist in javascript. Who knew?
 divToAdd.onmouseover = function() { picker.changeStyles(divToAdd, true); };
Where picker.changeStyles is a method on a class. Javascript is starting to grow on me.