String concatenation C# with List of Class
Clash Royale CLAN TAG#URR8PPP
String concatenation C# with List of Class
this may be very fundamental C# question as I only study C# myself there are things that I do not have the logic to start.
I have a class CustomerSite
with string Customer get;set
and string Site get;set;
CustomerSite
string Customer get;set
string Site get;set;
I create a list List<CustomerSite> listCustomerSite= new List<CustomerSite>();
List<CustomerSite> listCustomerSite= new List<CustomerSite>();
Assume, I have a list with the following data
SAMSUNG CHINA
SAMSUNG AMERICA
SAMSUNG AFRICA
LG CHINA
APPLE AMERICA
APPLE CHINA
I would like to have 1 concatenated string
string Result = "APPLE (AMERICA, CHINA), LG (CHINA), SAMSUNG (AFRICA, AMERICA, CHINA)"
string Result = "APPLE (AMERICA, CHINA), LG (CHINA), SAMSUNG (AFRICA, AMERICA, CHINA)"
How could I do that?
My idea is to use a dictionary to keep a list of distinct Customers and adding the site to the string but I still have no clue how to deal with sorting (AFRICA --> AMERICA --> CHINA)
(AFRICA --> AMERICA --> CHINA)
Dictionary<string, int> dictCustomer = new Dictionary<string, int>();
foreach (var i in listCustomerSite)
if (!dictCustomer.ContainsKey(i.Customer))
dictCustomer.Add(i.Customer, 0);
Result = Result + "," + "i.Customer" + "( i.Site) ";
else
Result.Replace(")", "," + i.Site + ")");
4 Answers
4
You can utilize LINQ and String.Join
to group your collection by customer, convert each grouping to a formatted string with sorted comma-separated sites, and then combine them to a single string:
String.Join
var customersWithLocations = listCustomerSite
.GroupBy(cs => cs.Customer)
.Select(g => $"g.Key (String.Join(", ", g.Select(cs => cs.Site).OrderBy(s => s)))")
.ToArray();
string result = String.Join(", ", customersWithLocations);
Just to make it clear:
.ToArray()
is not actually required in the first statement, because String.Join
can accept IEnumerable<string>
as an argument, but I personally prefer not to store IEnumerable<T>
as local variables to avoid possible multiple enumeration, while combining them into a single statement would make code less readable and messy. It shouldn't notably affect performance, but you may remove .ToArray()
if customersWithLocations
is not used in code further.– Yeldar Kurmangaliyev
Aug 10 at 16:19
.ToArray()
String.Join
IEnumerable<string>
IEnumerable<T>
.ToArray()
customersWithLocations
OP states "I still have no clue how to deal with sorting (AFRICA --> AMERICA --> CHINA)". This answer doesn't address the sorting requirement.
– Jon
Aug 10 at 16:21
@Jon, my bad, didn't notice it actually. I have update my answer, thanks!
– Yeldar Kurmangaliyev
Aug 10 at 16:22
I would add a
.OrderBy(g => g.Key)
after the GroupBy
to sort the customers.– Olivier Jacot-Descombes
Aug 10 at 16:31
.OrderBy(g => g.Key)
GroupBy
Thank you very much - works perfectly
– Secret
Aug 10 at 17:11
A one line LINQ statment can do it all:
var list = listCustomerSite
.GroupBy(c => c.Customer)
.Select(g => $"g.Key (string.Join(", ", g.Select(c => c.Site)))")
.ToList();
This actually does not fit the requirements 100%. OP wanted a single string result:
"I would like to have 1 concatenated string"
. This is a list...– maccettura
Aug 10 at 16:09
"I would like to have 1 concatenated string"
... nor does it address the requirement to have the output sorted alphabetically.
– Jon
Aug 10 at 16:20
This should produce the desired output, sorted as required:
public class CustomerSite
public CustomerSite(string customer, string site)
Customer = customer;
Site = site;
public string Customer get; set;
public string Site get; set;
class Program
static void Main(string args)
var listCustomerSite = new List<CustomerSite>()
new CustomerSite("SAMSUNG", "CHINA"),
new CustomerSite("SAMSUNG", "AMERICA"),
new CustomerSite("SAMSUNG", "AFRICA"),
new CustomerSite("LG", "CHINA"),
new CustomerSite("APPLE", "AMERICA"),
new CustomerSite("APPLE", "CHINA")
;
var list = from cs in listCustomerSite
group cs by cs.Customer into g
orderby g.Key
select $"g.Key (string.Join(", ", g.OrderBy(c => c.Site).Select(c => c.Site)))";
Console.WriteLine(string.Join(", ", list));
Console.ReadKey();
Output:
APPLE (AMERICA, CHINA), LG (CHINA), SAMSUNG (AFRICA, AMERICA, CHINA)
Hope this helps!
The idea of using a dictionary is good; however, I would operate in two steps:
I'm not going to use LINQ, as it will be more instructive and show the fundamental way of doing things (since you are learning C#).
I am using a SortedDictionary<TKey, TValue>
as it automatically sorts the entries by the key (the customers in our case).
SortedDictionary<TKey, TValue>
var dictCustomer = new SortedDictionary<string, SortedSet<string>>();
The idea is to use the customer name as key and a sorted set of sites as value. A SortedSet<T>
not only keeps the entries sorted, but also eliminates duplicates (which is not required here).
SortedSet<T>
foreach (CustomerSite customerSite in listCustomerSite)
if (dictCustomer.TryGetValue(customerSite.Customer, out var siteSet))
siteSet.Add(customerSite.Site);
else
siteSet = new SortedSet<string> customerSite.Site ;
dictCustomer.Add(customerSite.Customer, siteSet);
Now, let us build the result string:
var sb = new StringBuilder();
foreach (var keyValuePair in dictCustomer)
if (sb.Length > 0)
sb.Append(", ");
sb.Append(keyValuePair.Key).Append(" ("); // Appends the customer and " (".
bool nextSite = false;
foreach (string site in keyValuePair.Value)
if (nextSite)
sb.Append(", ");
sb.Append(site);
nextSite = true;
sb.Append(")");
string result = sb.ToString();
Note that a StringBuilder
is more efficient than concatenating strings directly, since a StringBuilder
uses a buffer internally which grows only as needed, while string concatenation creates a new string object at each step and involves copying an ever-growing string over and over.
StringBuilder
StringBuilder
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
maybe offtopic for your question but keep in mind that a dictionary doesn't guarantee the insertion order.
– gsharp
Aug 10 at 16:45