I am having trouble with a small section of code.
I have a List of a MapItem class with a couple properties, Address and Html, and I need to concatenate the Html properties for each item with an identica开发者_如何转开发l Address property For example:
firstMapItem = new MapItem { Address = "1122 Elm Street",
Html="<p>some html</p>" };
secondMapItem = new MapItem { Address = "1122 Elm Street",
Html="<p>different html</p>" };
would become:
firstMapItem.Address == "1122 Elm Street";
firstMapItem.Html == "<p>some html</p><p>different html</p>";
secondMapItem.Address == "1122 Elm Street";
secondMapItem.Html == "<p>some html</p><p>different html</p>";
This is what I have tried so far:
foreach (MapItem item in mapItems)
{
var sameAddress = from m in mapItems
where m.Address == item.Address
select m;
if (sameAddress.Count() > 1)
{
//tried inserting -> item.Html = ""; right here as well
foreach (MapItem single in sameAddress)
{
item.Html += single.Html;
}
}
}
I am probably making this more complicated than it needs to be.
Thanks in advance.
You could group by Address
and then concatenate the Html
values:
var results = from m in mapItems
group m by m.Address into ms
select new MapItem
{
Address = ms.Key,
Html = string.Concat(ms.Select(m => m.Html))
};
Use a grouping on the address, then just string.Join
the Html of all the items in the group to produce a new MapItem
:
var resultList = mapItems.GroupBy(m => m.Address)
.Select(g => new MapItem() { Address = g.Key, Html = string.Join("", g.Select(x => x.Html)) })
.ToList();
Edit:
Like the other solutions presented so far above approach will remove duplicates - that doesn't seem to be what you want - below a solution that creates a list that is not deduplicated (so will produce 2 items for the sample input)
var resultList = mapItems.GroupBy(m => m.Address)
.Select(g => g.Select( item => new MapItem() { Address = g.Key, Html = string.Join("", g.Select(x => x.Html)) } ))
.SelectMany( x=> x)
.ToList();
If you group by
Address, you'll end up with only one item when you have items with the same Address. If that's OK with, go with Group By
. However, if you need all the original items, with the Html concatenated, you should do like that:
var newMapItems = mapItems
.Select(mi => new MapItem() { Address = mi.Address,
Html = mapItems.Where(mi2 => mi2.Address == mi.Address)
.Select(mi3 => mi3.Html)
.Aggregate((acc, html) => acc += html)
}
);
You can do this with a GroupBy
and Select
:
var result = items
.GroupBy(m => m.Address, m => m.Html)
.Select(g => new MapItem() {Address = g.Key, Html = string.Concat(g.Select(h => h))});
This code should update your existing objects with appended values.
foreach (MapItem item in mapItems)
{
var sameAddress = from m in mapItems
group m by m.Address into ms
select string.Join("", ms.Select(e => e.Html).ToArray());
foreach (string concatHtml in sameAddress)
{
item.Html = concatHtml;
}
}
精彩评论