Wednesday, 21 October 2020

C# - LINQ - Running Total

Example 1

 

List<Country> CountryList = new List<Country> () { 

                 new Country { ID = 1, Name="United Kingdom", Month="JAN", Income=120},
                 new Country { ID = 2, Name="United Kingdom", Month="JAN", Income=125},
                 new Country { ID = 3, Name="United Kingdom", Month="JAN", Income=115},
                 new Country { ID = 4, Name="United Kingdom", Month="FEB", Income=125},
                 new Country { ID = 5, Name="United Kingdom", Month="MAR", Income=128},
                 new Country { ID = 1, Name="USA", Month="JAN", Income=110},
                 new Country { ID = 2, Name="USA", Month="FEB", Income=160},
                 new Country { ID = 3, Name="USA", Month="MAR", Income=160},
                 new Country { ID = 1, Name="Canada", Month="JAN", Income=100},
                 new Country { ID = 2, Name="Canada", Month="FEB", Income=90},
                 new Country { ID = 3, Name="Canada", Month="MAR", Income=80},
                 new Country { ID = 1, Name="Australia", Month="JAN", Income=105},
                 new Country { ID = 2, Name="Australia", Month="FEB", Income=95},
                 new Country { ID = 3, Name="Australia", Month="MAR", Income=85}
             };

 

 int runningTotal = 0;
 var a = CountryList.GroupBy(i => new { i.Name, i.Month })
                    .Select(g => new
                    {
                        CountryName = g.Key.Name,
                        Month = g.Key.Month,
                        Count = g.Count(),
                        Total = g.Sum(i => i.Income),
                        RunningTotal = runningTotal += g.Sum(i => i.Income),
                        Average = g.Average(i => i.Income)
                    }).ToList();

 

 

Example 2

List<int> list = new List<int>() { 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 69, 2007 };
int running_total = 0;
 
var result_set =
    from x in list
    select new
    {
        num = x,
        running_total = (running_total = running_total + x)
    };
 
foreach (var v in result_set)
{
    Console.WriteLine("list element: {0}, total so far: {1}",
        v.num,
        v.running_total);
}
 
Console.ReadLine();

 

Monday, 19 October 2020

C# - Lexicographic Order

Lexicographic Order

To put items in order, there must be a way to compare two items. With strings, the usual order is Lexicographic Order. This is dictionary order, except that all the uppercase letters preceed all the lowercase letters. This order is what the compareTo() method of class String uses.

Two strings are lexicographically equal if they are the same length and contain the same characters in the same positions. In this case, stringA.compareTo( stringB ) returns 0.

Otherwise, stringA.compareTo( stringB ) returns a negative value if StringA comes first and a positive value if StringB comes first.

Memory Aid: think of the strings in a dictionary as arranged from smallest to largest. Then stringA - stringB would produce a negative values if stringA came before StringB.

To determine which string comes first, compare corresponding characters of the two strings from left to right. The first character where the two strings differ determines which string comes first. Characters are compared using the Unicode character set. All uppercase letters come before lower case letters. If two letters are the same case, then alphabetic order is used to compare them.

If two strings contain the same characters in the same positions, then the shortest string comes first.


 

Relation

 

stringA.compareTo( stringB )

stringA

Less Than

stringB

Negative Integer

stringA

Equal

stringB

Zero

stringA

Greater Than

stringB

Positive Integer


Expression

Evaluates to

Explanation

"Zebra".compareTo("ant")

Negative Integer

upper case 'Z' comes before lower case 'a'

"Apple".compareTo("apple")

Negative Integer

upper case 'A' comes before lower case 'a'

"apple".compareTo("orange")

Negative Integer

'a' comes before 'o'

"maple".compareTo("morning")

Negative Integer

'a' comes before 'o'

"apple".compareTo("apple")

Zero

same length, same characters in same positions

"orange".compareTo("apple")

Positive Integer

'o' comes after 'a'

"applecart".compareTo("apple")

Positive Integer

longer string "applecart" comes after "apple"

"albatross".compareTo("albany")

Positive Integer

't' comes after 'n'


This is slightly confusing. Notice that stringA.compareTo(stringB) returns a negative integer when stringA and stringB are in the correct order.

 

Learning

When applied to numberslexicographic order is increasing numerical order, i.e. increasing numerical order (numbers read left to right). For example, the permutations of {1,2,3} in lexicographic order are 123, 132, 213, 231, 312, and 321. When applied to subsets, two subsets are ordered by their smallest elements.

Lexicographical order is alphabetical order. The other type is numerical ordering. Consider the following values:

1, 10, 2

Those values are in lexicographical order. 10 comes after 2 in numerical order, but 10 comes before 2 in "alphabetical" order.

 

Sunday, 18 October 2020

C# - LINQ - Recursive

//C# program that uses recursive method
using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
    static void Main()
    {
        // ... Call recursive method directly.
        List<int> list = new List<int>();
        X(list, 0);
 
        // ... Verify sum.
        Console.WriteLine(list.Sum());
    }
 
    static void X(List<int> list, int value)
    {
        if (list.Count < 10)
        {
            list.Add(value);
            X(list, value + 1);
        }
    }
}
 
 
//C# program that inlines recursive call
using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
    static void Main()
    {
        // ... Inline first recursive call.
        List<int> list = new List<int>();
        if (list.Count < 10)
        {
            list.Add(0);
            X(list, 0 + 1);
        }
 
        // ... Verify sum.
        Console.WriteLine(list.Sum());
    }
 
    static void X(List<int> list, int value)
    {
        if (list.Count < 10)
        {
            list.Add(value);
            X(list, value + 1);
        }
    }
}

Thursday, 15 October 2020

C# - LINQ - Using LINQ instead of Multiple Foreach Loops

 using System.Collections.Generic;

 namespace WorldCup

{

    public class Community

    {

        public List<Tournament> Tournaments = new List<Tournament>()

        {

            new Tournament { Rounds = new List<Round>()},

        };

    }

 

    public class Tournament

    {

        public List<Round> Rounds = new List<Round>()

        {

            new Round { Matches = new List<Match>()},

        };

    }

 

    public class Matches 

    {      

 

        public List<Round> Rounds = new List<Round>();

    }

 

    public class Round

    {

        public List<Match> Matches = new List<Match>();

    }

 

    public class Match

    {

        public Home home = new Home();

        public Away away = new Away();

 

        public class Home

        {

            int mParticipantId = 0;

            public int? ParticipantId

            {

                get { return mParticipantId; }

                set { value = mParticipantId ; }

            }

        }

 

        public class Away

        {

            int mParticipantId = 0;

            public int? ParticipantId

            {

                get { return mParticipantId; }

                set { value = mParticipantId; }

            }

        }

    }

}

 

MULTIPLE FOR LOOP

            var participantList1 = new List<int?>();

            var communities = new List<Community>();

 

            foreach (var community in communities)

            {

                foreach (var tournament in community.Tournaments)

                {

                    foreach (var round in tournament.Rounds)

                    {

                        foreach (var match in round.Matches)

                        {

                            if (match.home.ParticipantId.HasValue)

                            {

                                participantList1.Add(match.home.ParticipantId);

                            }

                            if (match.away.ParticipantId.HasValue)

                            {

                                participantList1.Add(match.away.ParticipantId);

                            }

                        }

 

                    }

                }

            }

 

LINQ Lamda Expression 

            var participantList = communities.SelectMany(c => c.Tournaments)

                                 .SelectMany(t => t.Rounds)

                                 .SelectMany(r => r.Matches)

                                 .Where(m => m.home.ParticipantId.HasValue ||

                                             m.home.ParticipantId.HasValue)

                                 .ToList();


C# - LINQ - CASE ..WHEN in LINQ

EXAMPLE 1

Int32[] numbers = new Int32[] { 1, 2, 1, 3, 1, 5, 3, 1 };

var numberText =

(

    from n in numbers

    where n > 0

    select new

    {

        Number = n,

        Text =

        (

            n == 1 ? "One" :

            n == 2 ? "Two" :

            n == 3 ? "Three" : "Unknown"

        )

    }

);

 

 EXAMPLE 2

from u in users

let range = (u.Age >= 0 && u.Age < 10 ? "0-25" :

             u.Age >= 10 && u.Age < 15 ? "26-40" :

             u.Age >= 15 && u.Age < 50 ? "60-100" :

            "50+")

group u by range into g

select new { g.Key, Count = g.Count() };



EXAMPLE 3

var query = from grade in sc.StudentGrade

join student in sc.Person on grade.Person.PersonID

equals student.PersonID

 select new

 {

     FirstName = student.FirstName,

     LastName = student.LastName,

     Grade = grade.Grade.Value >= 4 ? "A" :

                 grade.Grade.Value >= 3 ? "B" :

                 grade.Grade.Value >= 2 ? "C" :

                 grade.Grade.Value != null ? "D" : "-"

 };