static void Main(string[] args)
{
    LinkedList<Day> Days = new LinkedList<Day>();

    Day day1 = new Day() { sunUp = 800, sunDown = 1800 };
    Day day2 = new Day() { sunUp = 755, sunDown = 1805 };
    Day day3 = new Day() { sunUp = 750, sunDown = 1810 };
    Day day4 = new Day() { sunUp = 745, sunDown = 1815 };
    Day day5 = new Day() { sunUp = 740, sunDown = 1820 };

    Days.AddLast(day1);
    Days.AddLast(day2);
    Days.AddLast(day3);
    Days.AddLast(day4);
    Days.AddLast(day5);
    Console.WriteLine("There is an average of {0} minutes of night over the past {1} days.", Calculator(Days), Days.Count);
}
public static int ToMinutes(int time)
{
    return time / 100 * 60 + time - time / 100 * 100;
}
class Day
{
    public int sunUp;
    public int sunDown;
}

public static int Calculator(LinkedList<Day> Days)
{
    var current = Days.First;
    int nightDuration = 0;
    int count = 0; 
    while (current.Next != null)
    {
        nightDuration += ToMinutes(current.Value.sunDown) - ToMinutes(current.Next.Value.sunUp);
        current = current.Next;
        count++;
    }
    return nightDuration/count;

}

Requirement: Day must be stored in a LinkedList.

Is there a clean Lambda Expression equivalent to the Calculator method above? I am having trouble using Lambda's to calculate a function with variables across connected nodes.

Thanks for the help!

Cheers, Kyle

2

There are 2 answers

3
Jawad On BEST ANSWER

Quite a few things are wrong with your pseudo code of using a calculator (for addition in this instance)

You have a class that has two integers. I believe your idea is to add the two numbers together along with two numbers from every other node of the linked list. But, you are adding only the first number from Pair and adding it to 2nd number of the next node... dont think it will work.

array = current.value.int1 + current.Next.value.int2;

should be

array = current.value.int1 + current.value.int2;

Working Example

    public static int Calculator(LinkedList<Pair> Pairs)
    {
        var current = Pairs.First;
        int sum = 0;
        while (current != null)
        {
            sum += current.Value.num1 + current.Value.num2;
            current = current.Next;
        }
        return sum;
    }

Ran this in the main,

    LinkedList<Pair> Pairs = new LinkedList<Pair>();
    Pair pair = new Pair() { num1 = 1, num2 = 5 };
    Pairs.AddFirst(pair);
    Pairs.AddLast(pair);
    Pairs.AddLast(pair);
    Console.WriteLine( Calculator(Pairs));

Output

18

Lambda expression you can use to add up all the linked lists can be summed up as,

Console.WriteLine(Pairs.Sum(x => x.num1 + x.num2));

Output

18

Hope it helps

2
Scircia On

Looking at your example i see what you're trying to say. So you want to the same logic as in your Calculator method but using Lambda expression. The most easy way to do this is to use Language Integrated Query (LINQ).

So breaking up your Calculator() method we see it actually contains 2 elements.

  1. Sum up each value after you've combined num1 with num2 in the List
  2. Divide the end result with the total count in the list.

The most easy way to do this is by using Enumerable.Sum and then devide that value by the count of the list. For example:

Pairs.Sum(pair => pair.num1 + pair.num2) / Pairs.Count

Result: 6

Here a code example

Enumerable.Sum is extension method from System.Linq namespace. It returns sum of numeric values in collection.

Although Lambda expressions are awesome, please do bare in mind that readability is also very important. They are basically anonymous functions which, if the logic gets complex, will be hard to understand for other developers/team members.

Hope this helps. Good luck!


EDIT

So if i understand it correctly you're having a hard time using lambda expressions with nested methods. Like for example your Calculator() method makes use of another method ToMinutes.

Using the code from my first example, we can still use the logic. The most important part we have to change is the logic within the Sum. E.g.

Days.Sum(day => ToMinutes(day.sunDown) - ToMinutes(day.sunUp )) / totalDays;

This is just one of the ways to do it. Another option is to create an ExtensionMethod. E.g.

namespace ExtensionMethods
{
    public static class IntExtensions
     {
        public static int ToMinutes(this int time)
        {
            return time / 100 * 60 + time - time / 100 * 100;
        }
    }
}

Above the class you want to use the extension method just include it by writing

using ExtensionMethods;

at the top of your document.

This will give another option to all your integers to parse the value to a different value. In our case, to minutes.

int totalDays = Days.Count;
int averageMinutes = Days.Sum(day => day.sunDown.ToMinutes() - day.sunUp.ToMinutes()) / totalDays;
Console.WriteLine("There is an average of {0} minutes of night over the past {1} days.", averageMinutes, totalDays);

But again. This is one of the ways of doing it. I would recommend you to get and read C# in Depth by Jon Skeet and also dive into the clean code principles.

Anyways, i think i have made myself clear. See example code for more details.

Good luck!