4

I'm trying to create a list of tuples from a list using LINQ, but can't work out how to do it. What I've got is various data in an external file, which I'm reading sections using a standard method into a List<Single>, I then need to turn this into lists of groups of sequential elements of this list (which may have a variable number of elements in the groups). To state it another way:

List<Single> with n elements goes to List<Tuple<Single, Single>> with (n/2) elements

or

List<Single> with n elements goes to List<Tuple<Single, Single, Single>> with (n/3) elements

I couldn't work out how to do this with LINQ, so I've reverted to a for loop like, for example, so:

For i As Integer = 0 To CType(coords.Item2.Count / 3, Integer) Step 3
    normalList.Add( _
        New Tuple(Of Single, Single, Single)( _
            coords.Item2.Item(i), _
            coords.Item2.Item(i + 1), _
            coords.Item2.Item(i + 2) _
        ) _
    )
Next i

EDIT: I'm not at all worried about a generic solution, I'm interested in if it's possible to do this type of thing using LINQ. It seems to be outside the score of what it's intended for, but I don't have enough of a feel to know if this is true.

My question is is is it possible to accomplish the above type of task using LINQ. I've bashed around in the UI and google but have come up empty!

GHC
  • 2,658
  • 5
  • 30
  • 35
  • Impossible really, to do this in a strong-typed environment other than writing code for each possible occurrence of `n`. (Like there are many `Tuple` types). You either have to use dynamics or venture into F# where this would be peanuts. (But would require an interface to VB with dynamics anyway). – Gert Arnold Jun 03 '13 at 08:55
  • @GertArnold I'm not too worried about the generic solution - I'm trying to find out if it's possible to use LINQ to accomplish the task in hand for any one of the possible examples. I suspect I could make the solution more generic once I know how to do a single example. I've edited my question to make this clearer. Thank you! – GHC Jun 03 '13 at 09:04
  • 1
    _outside the score of what it's intended for_ That's right. LINQ is great for set operations (Where, Except, Union, ...) not for sequential stuff. It's possible to write [extension methods](http://stackoverflow.com/a/6852288/861716) that cut an IEnumerable into chunks of a specified number of elements but you can argue whether that's still LINQ. Usually classic `For/ForEach` look far less complicated. – Gert Arnold Jun 03 '13 at 09:15
  • @GertArnold Hmm. Thought so - I think it might be possible to do, but it's going to be really nasty. I've got as far as this: Dim x As New List(Of Single)({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) Dim o As Object = x.Select(Of Tuple(Of Integer, Single))(Function(val, index) New Tuple(Of Integer, Single)(CType(System.Math.Floor(index / 2), Integer), val)).GroupBy(Function(i) i.Item1)... which gets me a grouped set - I'd just need to work out how to aggregate them back into lists then into tuples - beats me how to do this though – GHC Jun 03 '13 at 09:20

2 Answers2

6

Maybe this will help someone.

var pairs = from p in TheListOfAllLists select (
new Tuple<string, string>( p.ParameterName,p.Value.ToString()));
JWP
  • 6,672
  • 3
  • 50
  • 74
5

It can be achieved (example for Tuple<Single, Single>) and the following solution isn't very complex, but using loop is clearer and - in case of this particular solution - more efficient (the input list is enumerated twice). Code in C#, don't know VB

var even = inputList.Where((elem, ind) => ind % 2 == 0);
var odd = inputList.Where((elem, ind) => ind % 2 == 1);
var outputList = even.Zip(odd, (a, b) => new Tuple<Single, Single>(a, b)).ToList();
lisp
  • 4,138
  • 2
  • 26
  • 43