Wednesday, July 26, 2017

Linq – Distinct - fun ?


Linq is nice. Usable. Readable. But … Distinct.
In short. There is no appropriate distinct in Linq.
What I mean “Appropriate” ?. Something like myList.Distinc(x=>x.id).
And there is nothing like that.

Possible solutions:

1. Group by

var queryLastNames =
        from student in students
        group student by student.LastName into newGroup
        orderby newGroup.Key
        select newGroup;

2. Morelinq library

  • it is a Nuget package
  • there is: 
    • myList.DistincBy(x=>x.id)
    • or myList.DistinctBy(x=>new {x.Id1,x.Id2,x.Id3)
  • it is from year 2009 … and it is still not implemented in Linq …
  • Thank you Pranay Rana

3. You can create your own TryToDictionary method


  private static Dictionary<T, K> TryToDictionary<T,K>(
         Func<K,T> getId,
         IEnumerable<K> list)
        {
            var result = new Dictionary<T, K>();
            foreach (var item in list)
            {
                if (result.ContainsKey(getId(item))) continue;
                result.Add(getId(item), item);
            }

            return result;
        }

        private static List<K> TryToUniqueList<T, K>(Func<K, T> getId, IEnumerable<K> list)
        {
            return TryToDictionary<T,K>(getId,list).Select(x => x.Value).ToList();
        }

4. Use original distinct with IEqualityComparer<T>

4.1 Implement IEqualityComparer<T>

.. Just if You really need one ...

4.2 But You can create a lambda version ! :-)

.. thank you Ruben Bartelink and Stackowerflow !

       public class LambdaEqualityComparer<T> : IEqualityComparer<T>
        {
            readonly Func<T, T, bool> _comparer;
            readonly Func<T, int> _hash;

            public LambdaEqualityComparer(Func<T, T, bool> comparer)
                : this(comparer, t => 0)
            {
            }

            public LambdaEqualityComparer(Func<T, T, bool> comparer, Func<T, int> hash)
            {
                _comparer = comparer;
                _hash = hash;
            }

            public bool Equals(T x, T y)
            {
                return _comparer(x, y);
            }

            public int GetHashCode(T obj)
            {
                return _hash(obj);
            }
        }

then you can use it like this

myList.Distinct(new LambdaEqualityComparer<MyClass>((x,y)=>x.Property1.Equals(y.Property1)));


4.2.3 You can  also create it as extension method ...

Sunday, July 2, 2017

Shelveset in TFS , git and subverson

First. What is shelveset.
In TFS ( Team Foundation Server from Microsoft) you can store yours changes on server for later use. You can specify the name, but also your developer name will be stored with that change. You can also specify if changes will be preserved on your pc (aka workspace/repository) or not.
Created shelveset you can  "unshelve" and use it whenever you need on the original pc, but, you can use that shelveset on another computer if needed , like when you are in another office, on a business trip, or simply when your pc is broken somehow, and also another colleague, whenever is located, can unshelve your shelveset.

So it is  quite useful.

But what about git ? Is there something similar ?

Yes, and no :-)
Git have a stash. You can stash , there is command for that, your changes, which then will be stored in "stash part" of git repository. But usually you are using local repository, so when you should use another computer you are lost. Of course you can commit and push your changes to remote/origin repository, so if you have a branch on remote repository , you will got something similar as TFS shelveset. There is also possibility to migrate stash from one repository to another, but I never tried that successfully ...
But there is advantage in comparison to TFS. TFS, it is a shame, is storing shelveset with branch information. So you can unshelve shelveset just into the same branch ! Crazy. Of course there is solution, but it is command line based ... Git stash can be "unstashed" into anyone branch.

But what about subversion (svn) ?
Yes there is something. A patch. You can create patch of your changes. It is one file which you can store whenever you like. If you will crate a folder under your subversion repository, you can also upload/commit your patch file into subversion  repository and then you or anybody else can use it .

Also there are other versioning systems like Mercurial but I never used them ;-)
Maybe in the future.