Reputation: 179
I am trying to parse the following string and get the result.
string test = "SiteA:Pages:1,SiteB:Pages:4,SiteA:Documents:6"
I am trying to get the following result after the split.
string SiteA = "Pages:1,Documents:6"
string SiteB = "Pages:4"
Here is my code but it doesn't seem to be working. How can I get all related "SiteA" and "SiteB"?
List<string> listItem = new List<string>();
string[] keyPairs = test.Split(',');
string[] item;
foreach (string keyPair in keyPairs)
{
item = keyPair.Split(':');
listItem.Add(string.Format("{0}:{1}", item[0].Trim(), item[1].Trim()));
}
Upvotes: 3
Views: 259
Reputation: 392833
using System;
using System.Linq;
using System.Text.RegularExpressions;
class MyClass
{
static void Main(string[] args)
{
string test = "SiteA:Pages:1,SiteB:Pages:4,SiteA:Documents:6";
var sites = test.Split(',')
.Select(p => p.Split(':'))
.Select(s => new { Site = s[0], Key = s[1], Value = s[2] })
.GroupBy(s => s.Site)
.ToDictionary(g => g.Key, g => g.ToDictionary(e => e.Key, e => e.Value));
foreach (var site in sites)
foreach (var key in site.Value.Keys)
Console.WriteLine("Site {0}, Key {1}, Value {2}", site.Key, key, site.Value[key]);
// in your preferred format:
var SiteA = string.Join(",", sites["SiteA"].Select(p => string.Format("{0}:{1}", p.Key, p.Value)));
var SiteB = string.Join(",", sites["SiteB"].Select(p => string.Format("{0}:{1}", p.Key, p.Value)));
Console.WriteLine(SiteA);
Console.WriteLine(SiteB);
}
}
Upvotes: 0
Reputation: 569
Here's a solution using LINQ:
string test = "SiteA:Pages:1,SiteB:Pages:4,SiteA:Documents:6";
var dict = test
.Split(',')
.GroupBy(s => s.Split(':')[0])
.ToDictionary(g => g.Key,
g => string.Join(",",
g.Select(i => string.Join(":", i.Split(':').Skip(1)))
.ToArray()));
Upvotes: 0
Reputation: 9562
This is what I would do (tested).
(However, does assume that all items will be correctly formatted). And of course, it's not really optimized.
static void Main(string[] args)
{
string test = "SiteA:Pages:1,SiteB:Pages:4,SiteA:Documents:6";
Dictionary<String, List<String>> strings = new Dictionary<string, List<string>>();
String[] items = test.Split(',');
foreach (String item in items)
{
List<String> itemParts = item.Split(':').ToList();
String firstPart = itemParts[0];
itemParts.RemoveAt(0);
String secondPart = String.Join(":", itemParts);
if (!strings.ContainsKey(firstPart))
strings[firstPart] = new List<string>();
strings[firstPart].Add(secondPart);
}
// This is how you would consume it
foreach (String key in strings.Keys)
{
List<String> keyItems = strings[key];
Console.Write(key + ": ");
foreach (String item in keyItems)
Console.Write(item + " ");
Console.WriteLine();
}
}
Upvotes: 0
Reputation: 38397
Here's my solution... pretty elegant in LINQ, you can use anonymous objects, Tuples, KeyValuePair, or your own custom class. I'm just using an anonymous type.
string test = "SiteA:Pages:1,SiteB:Pages:4,SiteA:Documents:6";
var results = test
.Split(',')
.Select(item => item.Split(':'))
.ToLookup(s => s[0], s => new { Key = s[1], Value = s[2] });
// This code just for display purposes
foreach (var site in results)
{
Console.WriteLine("Site: " + site.Key);
foreach (var value in site)
{
Console.WriteLine("\tKey: " + value.Key + " Value: " + value.Value);
}
}
Upvotes: 1
Reputation: 160852
I would use a Lookup
for this:
string test = "SiteA:Pages:1,SiteB:Pages:4,SiteA:Documents:6";
var listItemsBySite = test.Split(',')
.Select(x => x.Split(':'))
.ToLookup(x => x[0],
x => string.Format("{0}:{1}",
x[1].Trim(),
x[2].Trim()));
You can then use it like this:
foreach (string item in listItemsBySite["SiteA"])
{
Console.WriteLine(item);
}
Upvotes: 3
Reputation: 11210
Here is how I would do it:
SortedList<string, StringBuilder> listOfLists = new SortedList<string, StringBuilder>();
string[] keyPairs = test.Split(',');
foreach (string keyPair in keyPairs)
{
string[] item = keyPair.Split(':');
if (item.Length >= 3)
{
string nextValue = string.Format("{0}:{1}", item[1].Trim(), item[2].Trim());
if (listOfLists.ContainsKey(item[0]))
listOfLists[item[0]].Append(nextValue);
else
{
StringBuilder sb = new StringBuilder();
sb.Append(nextValue);
listOfLists.Add(item[0], sb);
}
}
}
foreach (KeyValuePair<string, StringBuilder> nextCollated in listOfLists)
System.Console.WriteLine(nextCollated.Key + ":" + nextCollated.Value.ToString());
Upvotes: 0
Reputation: 5340
Here is my code:
string test = "SiteA:Pages:1,SiteB:Pages:4,SiteA:Documents:6";
string[] data = test.Split(',');
Dictionary<string, string> dic = new Dictionary<string, string>();
for(int i = 0; i < data.Length; i++) {
int index = data[i].IndexOf(':');
string key = data[i].Substring(0, index);
string value = data[i].Substring(index + 1);
if(!dic.ContainsKey(key))
dic.Add(key, value);
else
dic[key] = string.Format("{0}, {1}", new object[] { dic[key], value });
}
Upvotes: 0