Reputation: 7582
I have a List inside List. As you can see from my foreach example, I go through flights first, and then through SEGMENTS, I print all segments from 1 flight in 1 line, only then I put NewLine for new flight, which can consist from 1 segment, or more segments. 1 Segment consist of departure time and arrival time.
When I use foreach I can put new line after each segment is finished, like this:
foreach (var flight in f)
{
foreach (var flight1 in flight.Segments.Where(x=>x.DepartureDate > DateTime.Now))
{
Console.Write(
"Departure: {0}, Arrival: {1}; ",
flight1.DepartureDate,
flight1.ArrivalDate);
}
Console.WriteLine(Environment.NewLine);
}
Result:
Departure: 2.9.2013 12:23:05, Arrival: 2.9.2013 2:23:05;
Departure: 2.9.2013 12:23:05, Arrival: 2.9.2013 2:23:05; Departure: 2.9.2013 3:2 3:05, Arrival: 2.9.2013 5:23:05;
This works nice. I am now interested how could I make this with Linq? I have my results with Linq, but all results are in one line, don't know where to put "NewLine" to put each flight segment into new line instead of all segments in one line... If I use Environment.NewLine, it will put each segment in new line. But segments from 1 flights should be in 1 line.
I use this Linq method:
public IEnumerable<Segment> GetActiveFlights(IEnumerable<Flight> flights)
{
var query = from flight in flights
from segment in flight.Segments
where segment.DepartureDate > DateTime.Now
select new Segment()
{
DepartureDate = segment.DepartureDate,
ArrivalDate = segment.ArrivalDate
};
return query;
}
I use this to iterate then:
IEnumerable<Flight> f = flightList.GetFlights();
foreach (var flight in flightFilter.GetActiveFlights(f))
{
Console.Write(
"Departure: {0}, Arrival: {1}; ",
flight.DepartureDate,
flight.ArrivalDate);
}
Result:
Departure: 2.9.2013 12:23:05, Arrival: 2.9.2013 2:23:05; Departure: 2.9.2013 12: 23:05, Arrival: 2.9.2013 2:23:05; Departure: 2.9.2013 3:23:05, Arrival: 2.9.2013 5:23:05; Departure: 2.9.2013 12:23:05, Arrival: 1.9.2013 6:23:05; Departure: 2. 9.2013 12:23:05, Arrival: 2.9.2013 2:23:05; Departure: 2.9.2013 5:23:05, Arrival
But here all my results are in one line. How can I make that each flight(which consist of multiple segments or 1) is written in new line.
Upvotes: 0
Views: 1605
Reputation: 63357
var query = flights.SelectMany(f=>
new []{ string.Join("", f.Segments
.Where(s=>s.DepartureDate > DateTime.Now)
.Select(s=>
string.Format("Departure: {0}, Arrival: {1}; ", s.DepartureDate, s.ArrivalDate))), Environment.NewLine});
foreach(var e in query)
Console.Write(e);
Upvotes: 0
Reputation: 15357
Console.Write(
String.Join(Environment.NewLine, f.Select(flight => {
var segments = flight.Segments.Where(x => x.DepartureDate > DateTime.Now);
return String.Join(" ", segments.Select(segment => {
return String.Format("Departure: {0}, Arrival: {1};", segment.DepartureDate, segment.ArrivalDate));
});
});
);
I personally prefer to have a Joined
extension method on IEnumerable<T>
which wraps String.Join
(taking a delimiter and an optional transformation delegate), and a Formatted
extension method on String
which wraps String.Format
:
var output =
f.Joined(Environment.NewLine, flight =>
flight.Segments
.Where(s => s.DepartureDate > DateTime.Now)
.Joined(" ", s => "Departure: {0}, Arrival: {1};".Formatted(s.DepartureDate, s.ArrivalDate))
);
Console.Write(output);
Upvotes: 3