1

Let's say I have a class with two numerical properties and I create a bunch of them.

public class TwoNumbers
{
    public TwoNumbers(int first, int second)
    {
        First = first;
        Second = second;
    }

    public int First { get; set; }
    public int Second { get; set; }
}

Is there a way using LINQ or lambda queries to add both First and Second of each object to a list of integers? For example:

List<TwoNumbers> twoNumbersList = new List<TwoNumbers>()
{
    new TwoNumbers(1,1),
    new TwoNumbers(32,59),
    new TwoNumbers(-12,200),
}

// Can I populate a list of integers upon assignment with a LINQ or lambda query?
List<int> integersVerbose = new List<int>()
foreach (var tn in twoNumbersList)
{
    integersVerbose .Add(tn.First);
    integersVerbose .Add(tn.Second);
}

// Desired syntax
var integersConcise = twoNumbersList. /* some expression */ .ToList(); // Automatically infers type from query

// Print the numbers
integersVerbose.Foreach(x => Console.WriteLine(x));
integersConcise.Foreach(x => Console.WriteLine(x));

// Expected output:
// 1
// 1
// 32
// 59
// -12
// 200 
// 1
// 1
// 32
// 59
// -12
// 200 

I am aware that there's a SelectMany method but it doesn't seem useful here because I'm not trying to extract a collection from an object, I just want a flat list with numbers.

0

3 Answers 3

2

You can use SelectMany if you project the two numbers into a collection:

List<TwoNumbers> twoNumbersList = new List<TwoNumbers> {
    new TwoNumbers(1,1),
    new TwoNumbers(32,59),
    new TwoNumbers(-12,200),
};

var results = twoNumbersList.SelectMany(nl => new[] { nl.First, nl.Second });

Output:

1
1
32
59
-12
200

Sign up to request clarification or add additional context in comments.

Comments

2

You could use SelectMany like this:

var integersConcise = twoNumbersList.SelectMany(x => new[] { x.First, x.Second });

And to avoid the array allocations you could create an IEnumerable property on your TwoNumbers class:

public class TwoNumbers
{
    //...

    public IEnumerable<int> Both { get { yield return First; yield return Second; } }
}

var integersConcise = twoNumbersList.SelectMany(x => x.Both);

Or even implement IEnumerable<int>:

public class TwoNumbers : IEnumerable<int>
{
    //...

    public IEnumerator<int> GetEnumerator()
    {
        yield return First;
        yield return Second;
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

var integersConcise = twoNumbersList.SelectMany(x => x);

Comments

0

Try GroupBy

            List<int> inputs = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            List<List<int>> outputs = inputs
                .Select((x, i) => new { x = x, i = i })
                .GroupBy(x => x.i / 2)
                .Select(x => new List<int>() {x.First().x, x.Last().x})
                .ToList();

1 Comment

You have it the other way around, I'm starting with a list of TwoNumbers and I want to make a flat list of integers from it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.