LINQ and Intersect

Assume that we have 3 list of integer.

They are

            
var listA = new List<int> {1,2,3,4,5};
var listB = new List<int> {2, 3, 6, 8,9 };
var listC = new List<int> { 3, 8, 13, 14, 15 };

The intersect of these 3 list are {3}

How can we get this result by LINQ?

It is pretty simple.

I provide two ways to do it.

Method A:

        public static List<T> ToIntersectAll<T>(this List<List<T>> lists)
        {
            HashSet<T> hashSet = null;
            foreach (var list in lists)
            {
                if (hashSet == null)
                {
                    hashSet = new HashSet<T>(list);
                }
                else
                {
                    hashSet.IntersectWith(list);
                }
            }
            return hashSet == null ? new List<T>() : hashSet.ToList();
        }

Method B:

        public static List<T> ToSimpleIntersectAll<T>(this List<List<T>> lists)
        {
            return lists.Aggregate((previousList, nextList) => previousList.Intersect(nextList).ToList());
        }

By calling these two methods, we need a List of List.

var listOfList = new List<List<int>> {listA, listB, listC};

After this, we can simple call the methods.

            var resultA = listOfList.ToIntersectAll();
            var resultB = listOfList.ToSimpleIntersectAll();

That is it.

CartesianProduct

Cartesian, if you don’t know what it is, please google it by yourself.

Thank you for reading.

 

        public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
        {
            //This is the normal way
            IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() };
            foreach (var sequence in sequences)
            {
                var localSequence = sequence;
                result = result.SelectMany(
                  _ => localSequence,
                  (seq, item) => seq.Concat(new[] { item })
                );
            }
            return result;

            //This is the linq way
            //IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
            //return sequences.Aggregate(
            //  emptyProduct,
            //  (accumulator, sequence) =>
            //    from accseq in accumulator
            //    from item in sequence
            //    select accseq.Concat(new[] { item }));
        }

Convert any string to a SHA 512 Hashed String

Sha 512 is a high security module, and the length of the generated string has about 130 characters.

Here is the definition for the extension.

        public static string ToHashedString(this string inputString)
        {
            var crypt = new SHA512Managed();
            //var crypt = new SHA256Managed();
            string hash = String.Empty;
            byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(inputString), 0, Encoding.UTF8.GetByteCount(inputString));
            return crypto.Aggregate(hash, (current, bit) => current + bit.ToString("x2"));
        }

Convert any IEnumerable to Select List

This little extension convert any type of IEnumerable to a Select List.

Here is the definition for the extension.

public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> items, Func<T, string> text, Func<T, string> value = null, Func<T, Boolean> selected = null)
        {
            return items.Select(p => new SelectListItem
            {
                Text = text.Invoke(p),
                Value = (value == null ? text.Invoke(p) : value.Invoke(p)),
                Selected = selected != null && selected.Invoke(p)
            });
        }

 

Here is how too call this extension.

					<div class="grid-9-12">                        
						@Html.DropDownListFor(x => x.AttributeModel.AttributeGroupId,
						Model.AttributeGroups.ToSelectList(y=>y.Name,y=>y.AttributeGroupId.ToString()),
						"Choose a attribute group...",
						new { @class = "chzn-select", style = "max-width: 350px;",tabindex="1" }) 
					</div>