Reputation: 32808
I have the following class called City that contains another class called Detail.
public class City
{
public override string PartitionKey { get; set; }
public override string RowKey { get; set; }
public string Title { get; set; }
public class Detail {
public Detail() {
Text = new HtmlText();
}
public HtmlText Text { get; set; }
}
}
public class HtmlText {
public HtmlText()
{
TextWithHtml = String.Empty;
}
[AllowHtml]
public string TextWithHtml { get; set; }
}
In my code I use the following to create a list of details. Later on I populate some of the details but not all.
IList<City.Detail> Details = Enumerable.Range(1,6).Select(x => new City.Detail()).ToList();
I need to be able to do two things. Can someone tell me the best way to do this. Hopefully using LINQ.
a) Remove any CityDetails from Details that have an empty Text field?
b) Add to the Details to make it have six City.Detail records if it has less than six?
Upvotes: 1
Views: 438
Reputation: 1510
a)
Details =
Details
.Except(Details
.Where(d => string.IsNullOrEmpty(d.Text.TextWithHtml)))
.ToList();
b)
Details =
Details
.Concat(
Enumerable
.Range(1, 6 - Details.Count())
.Select(x => new City.Detail()))
.ToList();
Upvotes: 0
Reputation: 56536
@YavgenyP answered your first question well. For the second question, here's what I'd recommend:
while (Details.Count < 6)
Details.Add(new City.Detail());
Trying to do this with LINQ is just all-around worse (length, readability, speed):
if (Details.Count < 6)
Enumerable.Range(1, 6 - Details.Count).Select(x =>
{
var d = new City.Detail();
Details.Add(d);
return d;
}).ToArray();
While I like his solution the best, here are some alternate ways to answer the first question:
foreach (var toRemove in Details.Where(cityDetail => cityDetail.Text == null || string.IsNullOrEmpty(cityDetail.Text.TextWithHtml)))
Details.Remove(toRemove);
foreach (var toRemove in (from cityDetail in Details
where cityDetail.Text == null || string.IsNullOrEmpty(cityDetail.Text.TextWithHtml)
select cityDetail))
Details.Remove(toRemove);
(from cityDetail in Details
where cityDetail.Text == null || string.IsNullOrEmpty(cityDetail.Text.TextWithHtml)
select Details.Remove(cityDetail)).ToArray();
Upvotes: 1
Reputation: 2123
Your first question can be solved by using this "query":
Details = Details.Where(cityDetail=>cityDetail.Text != null && !string.IsNullOrEmpty(cityDetail.Text.TextWithHtml)).ToList();
This will override ur details var and with the new list, including only the non empty items.
As of ur second question - its not really clear what u want to do, and you need to provide us with some more details/ explanations
Edit:
IEnumerable(T) represents a read only collection, which means it doesnt support removing items by definition. Of course you can add ur own RemoveWhere extension method, but it will essentially be doing the same thing ive done here
Upvotes: 1