José Luiz
José Luiz

Reputation: 333

Return a list of string using LINQ through a loop of conditionals

I have a class named Skill and I received a list of it through a parameter and I need to create a list of strings by LINQ that has some rules.

My Class

public class Skill {
        public int id {get;set;}
        public int year {get;set;}
        public int xp {get;set;}
    }

Dummy data:

var skills = new List<Skill>(){
            new Skill() { id=1, year = 9, xp = 95 } ,
            new Skill() { id=2, year = 5 } ,
        };

Rules: // year goes at max 10 // xp goes at max 100

The list of strings I must create is like this: for each year until 10 plus xp until 100 (if has)

    // '1-9-95'
    // '1-9-96'
    // '1-9-97'
    // '1-9-98'
    // '1-9-99'
    // '1-9-99'
    // '1-9-100'
    // '1-10-95'
    // '1-10-96'
    // '1-10-97'
    // '1-10-98'
    // '1-10-99'
    // '1-10-99'
    // '1-10-100'
    // '2-5'
    // '2-6'
    // '2-7'
    // '2-8'
    // '2-9'
    // '2-10'

I got it using for statement, but I was wondering about using LINQ.

Upvotes: 1

Views: 91

Answers (1)

Tim Schmelter
Tim Schmelter

Reputation: 460038

You need SelectMany and Enumerable.Range:

int maxYear = 10, maxXp = 100;
List<string> resultList = skills
    .Where(skill => skill.year <= maxYear && skill.xp <= maxXp) // skip invalid
    .SelectMany(skill => Enumerable.Range(skill.year, maxYear - skill.year + 1)
        .SelectMany(y => Enumerable.Range(skill.xp, maxXp - skill.xp + 1)
            .Select(xp => $"{skill.id}-{y}-{xp}")))
    .ToList();

.NET Fiddle: https://dotnetfiddle.net/c80wJs

I think i have overlooked that "(if has)", so you want to list xp only if available:

int maxYear = 10, maxXp = 100;
List<string> resultList = skills
    .Where(skill => skill.year <= maxYear && skill.xp <= maxXp) // skip invalid
    .SelectMany(skill => Enumerable.Range(skill.year, maxYear - skill.year + 1)
        .SelectMany(y => Enumerable.Range(skill.xp, skill.xp == 0 ? 1 : maxXp - skill.xp + 1)
            .Select(xp => skill.xp > 0 ? $"{skill.id}-{y}-{xp}" : $"{skill.id}-{y}")))
    .ToList();

.NET-fiddle for this (thanks to Rand Random): https://dotnetfiddle.net/06BIqg

Upvotes: 4

Related Questions