Skip to content

Linq - Exercise 1

Linq To Object - Exercise 1

/*
* Replace every 'TODO' * comment with the appropriate code to pass the tests * AND fulfill the requirements in the comments. * For all your code, don't use any loops, but Linq only to complete the tasks. */
// Create a set of elements first holding 1.000 objects of type Person.
// The IDs range from 0 to 999 and the items are shuffled.
var elements = Enumerable.Range(0, 1_000)
.OrderBy(n => Random.Shared.Next())
.Select(n => new Person { Id = n })
.ToList();
// Find the highest ID
int id = default;
// TODO
Assert("Find highest ID", id == 999);
// Find the element with the highest ID by choosing the element with the ID selected above
Person person = new Person();
// TODO
Assert("Find element with highest ID", person.Id == 999);
// Find the element with the highest ID by using the MaxBy method
Person person2 = new Person();
// TODO
Assert("Find element with highest ID with MaxBy", person2.Id == 999);
// Find the element with the highest ID by using the Aggregate method
Person person3 = new Person();
// TODO
Assert("Find element with highest ID with Aggregate", person3.Id == 999);
// Group elements by even/odd IDs
IEnumerable<Person> peopleWithEvenIds = Enumerable.Empty<Person>();
IEnumerable<Person> peopleWithOddIds = Enumerable.Empty<Person>();
// TODO
Assert("Group even/odd elements", peopleWithEvenIds.Count() == peopleWithOddIds.Count() && peopleWithEvenIds.Any());
// Let's create a second set of elements of type Person.
// This time the IDs range from 500 to 1.499,
// meaning the list overlaps with the first set of people.
var elements2 = Enumerable.Range(500, 1_000)
.OrderBy(n => Random.Shared.Next())
.Select(n => new Person { Id = n })
.ToList();
// Find intersection of elements and elements2 via their IDs
IEnumerable<Person> intersection = Enumerable.Empty<Person>();
// TODO
Assert("Find intersection",
intersection.Count() == 500
&& intersection.Min(p => p.Id) == 500
&& intersection.Max(p => p.Id) == 999);
// Find union of elements and elements2 via their IDs, removing duplicates
IEnumerable<Person> personUnion = Enumerable.Empty<Person>();
// TODO
Assert("Find union",
personUnion.Count() == 1_500
&& personUnion.DistinctBy(p => p.Id).Count() == 1_500);
// Let's create another set of elements.
// This time it's objects of type Items.
// A Person can own an Item. If so the Item's OwnerId will be equal to the Owner's ID.
var items = Enumerable.Range(0, 1_500_000)
.Select(n => new Item
{
Id = n,
OwnerId = Random.Shared.Next(1_499)
})
.ToList();
// Make sure that every owner ID in items is an existing ID in the union of elements and elements2
var condition = false /*TODO*/;
Assert("Verify OwnerIds exist",
condition);
// Join Items with their owners using a Linq Query Expression (from ... in ... join ...)
IEnumerable<ItemMapping> itemMappings1 = Enumerable.Empty<ItemMapping>();
// TODO
Assert("Join tables with Linq Query Expression", itemMappings1.Count() == 1_500);
// Join Items with their owners using Linq with Lambda Expressions
IEnumerable<ItemMapping> itemMappings2 = Enumerable.Empty<ItemMapping>();
// TODO
Assert("Join tables with Lambda Expressions", itemMappings2.Count() == 1_500);
// Make sure both approaches yield the same result
Assert("Verify Join approaches yield same result", false /* TODO */);
// Make sure the results are correct,
// meaning an ItemMapping should only contain items
// where the OwnerId matches the owner inside the same mapping.
Assert("Verify Join yields correct result", false /* TODO */);
// Use SelectMany to select all items from the itemMappings1 into one Enumerable
IEnumerable<Item> selectedItemsFromMappings = Enumerable.Empty<Item>();
// TODO
Assert("Use select many to flatten results", selectedItemsFromMappings.DistinctBy(i => i.Id).Count() == 1_500_000);
var families = new List<Family>
{
new Family
{
ClanName = "Mighty Maniacs",
MonthlyIncome = new List<decimal>
{ 10,
20
}
}, new Family
{
ClanName = "Humble Humans",
MonthlyIncome = new List<decimal>
{ 50,
70
}
}};
decimal result = families
.Where(f => f.ClanName.Contains("Humans"))
.Select(f => f.MonthlyIncome.Sum())
.Average();
decimal result2 = families
.Where(f => f.ClanName.Contains("Humans"))
.Average(f => f.MonthlyIncome.Sum());
////////////////////////////////////////////////////
/// Predefined Methods and classes.
/// Do not change!
////////////////////////////////////////////////////
static void Assert(string description, bool condition)
{
if (condition)
{ Console.WriteLine($"PASSED - {description}");
} else
{
Console.Error.WriteLine($"FAIL - {description}");
}}
class Person
{
public int Id { get; set; }
public string Name { get => $"Person {Id}"; }
}
class Family
{
public string ClanName { get; set; }
public IEnumerable<decimal> MonthlyIncome { get; set; }
}
class FamilyMember
{
public string Name { get; set; }
}
class Item
{
public int Id { get; set; }
public string Name { get => $"Item {Id}"; }
public int OwnerId { get; set; }
}
class ItemMapping
{
public Person Owner { get; set; }
public IList<Item> Items { get; set; }
}