Reputation: 2027
I have a string having two different types of data in alternating rows (i.e. two rows make one record). I want to select only those records where length of 2nd (i.e. even row) is less than 1000.
I have tried this but it results in selecting only the eventh row and discards the odd row:
var lessthan1000Length = recordsFile.Where((src, index) => src.Length<1000 && index%2 != 0);
Sample data from recordsFile
2012-12-04 | 10:45 AM | Lahore
Added H2SO4 in the solution. Kept it in the lab temperature for 10 minutes
2012-12-04 | 10:55 AM | Lahore
Observed the pH of the solution.
2012-12-04 | 11:20 AM | Lahore
Neutralized the solution to maintain the pH in 6-8 range
Thanks for your guidance.
P.S: Kindly note that the results are required in the form of List<string>
as we have to make a new dataset from it.
Upvotes: 1
Views: 664
Reputation: 117154
If you use Microsoft's Reactive Framework team's "Interactive Extensions" you get a nice extension method that can help you.
var query =
from pair in lines.Buffer(2)
where pair[1].Length < 1000
select pair;
var results = query.ToList();
From your sample data I get this:
Just NuGet "Ix-Main" to get the extension methods - there are a lot more there than just .Buffer
and many of them are super useful.
Upvotes: 1
Reputation: 62002
Alexander's answer seems to work fine.
Alternatively, you can create a method to turn a sequence (with an even number of terms) into a sequence of pairs. I guess something like:
static IEnumerable<Tuple<T, T>> PairUp<T>(this IEnumerable<T> src)
{
using (var e = src.GetEnumerator)
{
while (e.MoveNext())
{
var first = e.Current;
if (!e.MoveNext())
throw new InvalidOperationException("Count of source must be even"); // OR: yield break; OR yield return Tuple.Create(first, default(T)); yield break;
var second = e.Current;
yield return Tuple.Create(first, second);
}
}
}
With that you could do recordsFile.PairUp().Where(t => t.Item2.Length < 1000)
or similar.
Edit: Since you want the two "parts" concatenated as strings, that would be recordsFile.PairUp().Where(t => t.Item2.Length < 1000).Select(t => t.Item1 + t.Item2)
.
Upvotes: 1
Reputation: 110201
List<string> result = recordFile
.Select( (str, index) => new {str, index})
.GroupBy(x => x.index / 2, x => x.str)
.Where(g => g.Last().Length < 1000)
.Select(g => g.First() + g.Last())
.ToList();
Upvotes: 2
Reputation: 14251
var odds = recordsFile.Where((str, index) => index % 2 == 0);
var evens = recordsFile.Where((str, index) => index % 2 == 1);
var records = odds.Zip(evens, (odd, even) => new { odd, even })
.Where(pair => pair.even.Length < 1000);
foreach (var record in records)
Console.WriteLine(record);
Upvotes: 5