GirlCode
GirlCode

Reputation: 85

Ho to get Key and Value in LINQ from Score percentile

Hi I'm reading a book called "Thinking in LINQ", at page 11 there's the below code snippet which if using LINQPad it displays properly (Key and Value columns)... However, I'm testing all the book code example in C# / Console App as I'm working in C# at work, not in LINQ...

so how would i get the same result in a C#? as I tried many things but doesn't not display the value, only the key.

PS : I know that in the book they used Dump but VS has no Dump method, we can replace Dump by a variable assignation, and use the variable in a Console.WriteLine to display data. I tried it in another example of the book and worked well.

    static void Main(string[] args)
    {

        int[] nums = { 20, 15, 31, 34, 35, 40, 50, 90, 99, 100 };

        nums.ToLookup(k => k, k => nums.Where(n => n < k))
            .Select(k => new KeyValuePair<int, double>
                (k.Key, 100 * ((double)k.First().Count() / (double)nums.Length)));


        foreach (var item in nums)
        {
            Console.WriteLine("{0}", item);
        }


        Console.Read();
    }
}

enter image description here

enter image description here

enter image description here

Upvotes: 1

Views: 202

Answers (4)

Pavel Anikhouski
Pavel Anikhouski

Reputation: 23238

You forgot to assign the Select method result to a variable in your code, currently you are enumerating the source nums collection. Select returns an IEnumerable<KeyValuePair<int,double>> instance, it isn't changing the source collection. You should assign this instance and enumerate then

var result = nums.ToLookup(k => k, k => nums.Where(n => n < k))
    .Select(k => new KeyValuePair<int, double>
        (k.Key, 100 * ((double)k.First().Count() / (double)nums.Length)));

foreach (var item in result)
{
    Console.WriteLine("{0}", item);
}

Code in book also uses the Dump method from LinqPad, which is missing in your code. Actually this method will produce the useful output, which you will see in the book

Upvotes: 1

sam
sam

Reputation: 1985

In C# you are just printing nums collection using for loop. The screenshot of the book shows, there is Dump at the end of converting to lookup. So, in order to get exact same result, you need to enumerate nums after converting to lookup as shown below: (ToLookup won't modify base collection which is nums integer collection to key-value pair collection by invoking the method.)

static void Main(string[] args)
{

    int[] nums = { 20, 15, 31, 34, 35, 40, 50, 90, 99, 100 };

    var numsLookup = nums.ToLookup(k => k, k => nums.Where(n => n < k))
        .Select(k => new KeyValuePair<int, double>
            (k.Key, 100 * ((double)k.First().Count() / (double)nums.Length)));

    Console.WriteLine("\tKey\t\tValue");
    Console.WriteLine("================");
    foreach (var item in numsLookup)
    {
        Console.WriteLine("{0}\t\t {1}", item.Key, item.Value);
    }


    Console.Read();
}

Upvotes: 0

Krishna Varma
Krishna Varma

Reputation: 4260

You should take the LINQ to another variable

int[] nums = { 20, 15, 31, 34, 35, 40, 50, 90, 99, 100 };

var results =  nums.ToLookup(k => k, k => nums.Where(n => n < k))
                  .Select(k => new KeyValuePair<int, double>
                    (k.Key, 100 * ((double)k.First().Count() / (double)nums.Length)));


foreach (var item in results)
{
     Console.WriteLine("{0}", item);
}


Console.Read();

Upvotes: 1

aloisdg
aloisdg

Reputation: 23521

Try assigning nums to a new variable (e.g. items):

Try it online!

static void Main(string[] args)
{

    int[] nums = { 20, 15, 31, 34, 35, 40, 50, 90, 99, 100 };

    // here we go
    var items = nums.ToLookup(k => k, k => nums.Where(n => n < k))
        .Select(k => new KeyValuePair<int, double>
            (k.Key, 100 * ((double)k.First().Count() / (double)nums.Length)));


    foreach (var item in items)
    {
        Console.WriteLine("{0}", item);
    }


    Console.Read();
}

Upvotes: 1

Related Questions