Showing posts with label linq. Show all posts
Showing posts with label linq. Show all posts

Thursday, August 7, 2014

C# finding duplicates in a List using LINQ



Suppose you have a list that contains entries repeated more than once.
Using LINQ you can get the repeated elements and their values.

The easiest way to solve the problem is to group the elements based on their value, and then pick a rapresentative of the gorup if the elements in it are more than 1.
In linq, this translates to:
    var query = lst.GroupBy(x=>x)

              .Where(g=>g.Count()>1)

              .Select(y=>y.Key)

              .ToList();

You can replace x=>x with x => x.Property if your list is a list of complex objects and you want to search for a specific duplicate value. If you compare objects you need to override equals.
If you want to know how many times the elements are repeated, you can use:

    var query = lst.GroupBy(x=>x)

              .Where(g=>g.Count()>1)

              .Select(y=> new { Element = y.Key, Counter = g.Count()})

              .ToList();

Submit this story to DotNetKicks

Friday, January 27, 2012

C# getting file names without extensions


When you walk a directory getting file names you get a file name with its extension: file1.txt, file2.txt, file3.txt.
How can you get file names without file extensions file1, file2, file3?

DirectoryInfo d = new DirectoryInfo(myDirectory);
FileInfo[] fileArrray = d.GetFiles("*.txt");
foreach (FileInfo f in smFiles)
{
   var fileNameOnly = Path.GetFileNameWithoutExtension(f.Name);
   
   //...
   //process file...
}

Thre is also a linq way:

var filenames = String.Join(", ", Directory.GetFiles(@"c:\", "*.txt")
.Select(filename => Path.GetFileNameWithoutExtension(filename)).ToArray());

Submit this story to DotNetKicks

Thursday, January 19, 2012

What is a Method Group?

A method group is the name for a set of methods (that might be just one).
The ToString function has many overloads - the method group would be the group consisting of all the different overloads for that function.
It is a compiler term for "I know what the method name is, but I don't know the signature"; it has no existence at runtime, where it is converted in the correct overload.
Also, if you are using LINQ, you can apparently do something like myList.Select(methodGroup).
so you can replace this code:
private static int[] ParseInt(string s)
{
    var t = ParseString(s);
    var i = t.Select(x => int.Parse(x));
    return i.ToArray();
}
with this one:
private static int[] ParseInt(string s)
{
    var t = ParseString(s);
    var i = t.Select(int.Parse);
    return i.ToArray();
}

Submit this story to DotNetKicks

Saturday, January 14, 2012

Shuffle in linq (part 2)

There are many times when we need to randomly sort a list or array.
The simplest idea is to use Random.Next().

Here is the code:
public static class ShuffleExtensions
{
    public static IEnumerable<tsource>
           RandomShuffle<tsource>(this IEnumerable<tsource> source)
    {
        var rand = new Random();
        return source.Select(t => new {
                Index = rand.Next(),
                Value = t })
            .OrderBy(p => p.Index)
            .Select(p => p.Value);
    }
}

The main problem with using Random.Next() is that it is not really random. Every number will be the first in the sequence based on the supplied seed. If you call it twice with the same seed (i.e. within one tick) you will get the same number.
The distribution of random numbers over your range will be very poor and a chi-square statistical test won't do too well either to test your set of numbers for a large number of iterations.
A better approach may be using System.Guid.NewGuid() function call. This returns a new GUID for each item in the array. Since GUID's are unique and non-repeating, this guarantees each item has a unique id. LINQ OrderBy will then sort the array by the list of GUID's returned.

Here is the code:
public static class ShuffleExtensions
{
    public static IEnumerable<tsource>
           RandomShuffle<tsource>(this IEnumerable<tsource> source)
    {
        return source.Select(t => new {
                Index = System.Guid.NewGuid(),
                Value = t })
            .OrderBy(p => p.Index)
            .Select(p => p.Value);
    }
}

You can write a simple test for verify the implementations.

Here is the code:
public static void TestRandomShuffle()
{
    // create and populate the original list with 1000 elements
    var l = new List<int>(100);
    for (var i = 0; i < 100; i++)
        l.Add(i);

    var shuffled = l.RandomShuffle().ToArray();
    for (var i = 0; i < 100; i++) 
        Debug.Write(i + ":" + shuffled[i].ToString() + ",");
}

As a final notice, remember that John von Neumann said:
Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin.
:)

Submit this story to DotNetKicks

Thursday, December 15, 2011

Shuffle in Linq (Part 1)

A simple implementation for shuffling a list in linq.
public static class ShuffleExtensions
{
    public static IEnumerable<tsource> 
           RandomShuffle<tsource>(this IEnumerable<tsource> source)
    {
        var rand = new Random();
        return source.Select(t => new { 
                Index = rand.Next(), 
                Value = t })
            .OrderBy(p => p.Index)
            .Select(p => p.Value);
    }
}

Submit this story to DotNetKicks