split string array c# - c#

So I have multiple arrays of strings. Within each array I have a string which uses '|' as a separator. What I need is to create a string with the first elements of the array up until the '|'.
So in the example I need 6485,6486,6487,6509,6510,6511,6533,6534,6535,|

Use String.Split() to split the original strings, then store the first ones in a separate array, then use String.Join() to concatenate them
string[] tempStrings = new string[stringArray.Length];
for(int i = 0; i < stringArray.Length; i++)
{
tempStrings[i] = stringArray[i].Split(#"|")[0];
}
string result = String.Join(",", tempStrings);

Using System.Linq :
string[] temp = new string[] { "1,2,3|4,5,6|7,8,9", "10,11,12|13,14,15", "16,17,18"};
var result = String.Join(",", temp.Select(x => x.Split('|').FirstOrDefault())
.ToList());
With null and empty values :
string[] temp = new string[] { "1,2,3|4,5,6|7,8,9", "10,11,12|13,14,15", "16,17,18", "", null };
var result = String.Join(",", temp.Select(x => x?.Split('|').FirstOrDefault())
.Where(x => !string.IsNullOrWhiteSpace(x))
.ToList());

Related

c# substring from a word in quotes

I am trying to use substring to get a value from a string as such:
surname='Smith',name="John"
I basically want to use the text "name" and the quotes to get the value "John"..
Is there a way to do this please?
you could use linq query to get name
var query = #"surname='Smith',name = \""John\""";
var name = query
.Split(',')
.Select(s => new KeyValuePair<string, string>(
s.Split('=').GetValue(0).ToString().Trim(),
s.Split('=').GetValue(1).ToString().Trim()
))
.FirstOrDefault(kvp => kvp.Key == "name").Value;
Console.WriteLine(name);
There are many ways to do that.
That is one:
char[] quotes = { '\'', '\"' };
string input = "surname='Smith',name=\"John\"";
string[] sections = input.Split(',');
for (int i = 0; i < sections.Length; i++)
{
string[] pair = sections[i].Split('=');
if (pair[0] == "surname")
Debug.WriteLine("surname=" + pair[1].Trim(quotes));
if (pair[0] == "name")
Debug.WriteLine("name=" + pair[1].Trim(quotes));
}

Cut last character from string which was earlier splitted by char

I want to order list with string names by name included in brackes.
List<string> result = new List<string>();
list.ForEach(elem => result.Add(elem.Value));
result.Add(item);
result = result.OrderBy(o=>o.Split(';')[0].Substring(0, o.Length - 1).Split('(')[1]).ToList();
Example: 2-osobowy(Agrawka);Śniadanie+Obiadokolacja
I want to extract this name Agrawka
How to change instruction Substring(0, o.Length - 1)to cut last char from splitted string in orderby instruction?
If I right understood you want extract values in the brackets and sort input' list by that values. So code below sorts your data and extracts value to additional list:
List<string> resultList = new List<string>() { "2-osobowy(Bgrawka);Śniadanie+Obiadokolacja", "2-osobowy(Agrawka);Śniadanie+Obiadokolacja" };
string tempStr = null;
var extractedStr = new List<String>();
resultList = resultList.OrderBy(o =>
{
var extract = (tempStr = o.Split(';')[0].Split('(')[1]).Substring(0, tempStr.Length - 1);
extractedStr.Add(extract);
return extract;
}).ToList();
If you want only sort input data just simplify the lambda:
resultList = resultList.OrderBy(o => (tempStr = o.Split(';')[0].Split('(')[1]).Substring(0, tempStr.Length - 1)).ToList();

Loop through a List<string> but only take a part of each string inside

I am wondering if anyone can help me, I am trying to loop through a list of strings but only take the part to the left of ":" but not including the ":" I can do this with the approach below but I am trying to implement this by using Linq instead. Any help would be greatly appreciated.
List<string> Results = new List<string>();
List<string> strings = new List<string>
{
"121:sdfdsfds",
"122:sdfdsfds",
"123:sdfdsfds"
};
for (var i = 0; i < strings.Count; i++)
{
string[] tokens = strings[i].Split(':');
if (tokens.Any())
{
Results.Add(tokens[0]);
}
}
Use the Select method (System.Linq namespace)
class Program
{
static void Main(string[] args)
{
List<string> strings = new List<string>
{
"121:sdfdsfds",
"122:sdfdsfds",
"123:sdfdsfds"
};
List<string> Results = strings
.Select(s => s.Split(':')[0])
.ToList();
Results.ForEach(s => Console.WriteLine(s));
Console.ReadKey();
}
}
Output:
121
122
123
Method chain syntax:
List<string> Results = strings.Select(t => t.Split(':'))
.Where(tokens => tokens.Any())
.Select(tokens => tokens[0]).ToList();
Query syntax:
List<string> Results = (from t in strings
select t.Split(':')
into tokens
where tokens.Any()
select tokens[0]).ToList();
List<string> Results = strings
.Select(item => item.Split(':').FirstOrDefault())
.Where(item => item != null).ToList();
You can take each item of the string array, split it, and return index[0] all inside a select statement:
var results = strings.Select(i => i.Split(':')[0]).ToList();
If there's a chance that some items will be empty and you don't want to include them, you can use this syntax on the string.Split method:
var results = strings
.Select(i => i.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries)
.FirstOrDefault())
.Where(i => i != null)
.ToList();
Use forEach,
strings.ForEach(x => Results.Add(x.Split(':')[0]));

Splitting an array into 2D or two arrays

I have a text file that I am reading to pull out register values and what they contain.
2 lines from the array pulled out is: (full list is about 700)
0x0003 = 0x0069
0x0007 = 0x0078
I would like to split these into two arrays or one 2-dimensional array, whatever is best(I am new to using arrays)
My goal is to search the array for example for register 3, find the index then extract the information from the 2nd arrays corresponding index.
Here is my code so far ,
List<string> registerFullList1 = new List<string>();
for (int i = 0; i < 2000; i++)
{
string[] importStringArray1 = new string[2000];
importStringArray1[i] = importStringArray1[i] + objReader.ReadLine() + "\r\n";
//code to extract register info from string array
string listsplit1 = Regex.Match(importStringArray1[i], #"(?<= 0x)[0-9A-Fa-z\s\=]{13}").Value;
if (listsplit1.Contains("0x")) //code to add to list only registers and ignore empty lines
{
registerFullList1.Add(Convert.ToString(listsplit1));
}
}
int[] index = new int[2000]; // is there a way here that I don't have to assign 0,1,2,3 to each assignment?
index[0] = registerFullList1.FindIndex(x => x.StartsWith("0003 ="));
Register3.Text = Regex.Match(registerFullList1[index[0]], #"(?<= 0x)[0-9A-F]{4}").Value;
index[1] = registerFullList1.FindIndex(x => x.StartsWith("0007 ="));
Register7.Text = Regex.Match(registerFullList1[index[1]], #"(?<= 0x)[0-9A-F]{4}").Value;
This all works no problem and I am displaying the register content in text boxes. But I would like two arrays so it is more proper, one with register numbers and one with content. I cant figure it out, any help would be appreciated.
UPDATE
final code after reading answers,
List<string> registerNumberList = new List<string>();
List<string> registerContentList = new List<string>();
List<string> registerFullList = new List<string>();
for (int i = 0; i < 2000; i++)
{
string[] importStringArray1 = new string[2000];
importStringArray1[i] = importStringArray1[i] + objReader.ReadLine() + "\r\n";
string listsplit1 = Regex.Match(importStringArray1[i], #"(?<= 0x)[0-9A-Fa-z\s\=]{13}").Value; // #"(?<== 0x)[0-9A-F]{4}"
string listsplit2 = Regex.Match(importStringArray1[i], #"(?<= 0x)[0-9A-Fa-z\s\=]{4}").Value;// pulls out the register number from original array
string listsplit3= Regex.Match(importStringArray1[i], #"(?<== 0x)[0-9A-Fa-z\s\=]{4}").Value;//pulls out register content from original array
if (listsplit1.Contains("0x"))
{
registerNumberList.Add(Convert.ToString(listsplit3));//makes a list with register numbers
registerContentList.Add(Convert.ToString(listsplit2) );//makes a list with register content
registerFullList.Add(Convert.ToString(listsplit2) + "=" + Convert.ToString(listsplit3));//the full list
}
}
Dictionary <string, string> registers = registerFullList.Select(line => line.Split('=')
.ToArray())
.ToDictionary(items => items[0], items => items[1]); //joins the register numbers and content into a dictionary with just 4 decimal values for each
list1.Text = String.Join("\r\n", registerFullList);
list2.Text = registers["0010"]; // pulls out register info
Thanks guys
I suggest using Linq:
If you insist on the array:
int[][] result = File
.ReadLines(#"C:\myFile.txt")
.Select(line => line
.Split('=')
.Select(item => Convert.ToInt32(item, 16))
.ToArray())
.ToArray();
In case first index is unique one (and thus can serve as a key) you can materialize the data as a dictionary:
Dictionary<int, int> result = File
.ReadLines(#"C:\myFile.txt")
.Select(line => line
.Split('=')
.Select(item => Convert.ToInt32(item, 16))
.ToArray())
.ToDictionary(items => items[0], items => items[1]);
...
// value == 0x0078 (120)
int value = result[0x0007];
Try using a dictionary :
Dictionary<string, string> registersKeyValue = new Dictionary<string, string>();
string content = registersKeyValue
.Where(keyValuePair => keyValuePair.Key == "0x0003")
.FirstOrDefault()
.Value;

Sorting a string based on prefixes

If you are given an array with random prefixes, like this:
DOG_BOB
CAT_ROB
DOG_DANNY
MOUSE_MICKEY
DOG_STEVE
HORSE_NEIGH
CAT_RUDE
HORSE_BOO
MOUSE_STUPID
How would i go about sorting this so that i have 4 different arrays/lists of strings?
So the end result would give me 4 string ARRAYS or lists with
DOG_BOB,DOG_DANNY,DOG_STEVE <-- Array 1
HORSE_NEIGH, HORSE_BOO <-- Array 2
MOUSE_MICKEY, MOUSE_STUPID <-- Array 3
CAT_RUDE, CAT_ROB <-- Array 4
sorry about the names i just made them up lol
var fieldNames = typeof(animals).GetFields()
.Select(field => field.Name)
.ToList();
List<string> cats = new List<string>();
List<string> dogs = new List<string>();
List<string> mice= new List<string>();
List<string> horse = new List<string>();
foreach (var n in fieldNames)
{
var fieldValues = typeof(animals).GetField(n).GetValue(n);"
//Here's what i'm trying to do, with if statements
if (n.ToString().ToLower().Contains("horse"))
{
}
}
So i need them to be splitted into STRING ARRAYS/STRING LISTS and NOT just strings
string[] strings = new string[] {
"DOG_BOB",
"CAT_ROB",
"DOG_DANNY",
"MOUSE_MICKEY",
"DOG_STEVE",
"HORSE_NEIGH",
"CAT_RUDE",
"HORSE_BOO",
"MOUSE_STUPID"};
string[] results = strings.GroupBy(s => s.Split('_')[0])
.Select(g => String.Join(",",g))
.ToArray();
Or maybe something like this
List<List<string>> res = strings.ToLookup(s => s.Split('_')[0], s => s)
.Select(g => g.ToList())
.ToList();
var groups = fieldNames.GroupBy(n => n.Split('_')[0]);
Usage
foreach(var group in groups)
{
// group.Key (DOG, HORSE, CAT, etc)
foreach(var name in group)
// all names groped by prefix
}
foreach (String s in strings)
{
if (s.StartsWith("CAT_")
cats.Add(s);
else if (s.StartsWith("HORSE_")
horses.Add(s);
// ...
}
Or:
foreach (String s in strings)
{
String[] split = s.Split(new Char [] { '_' });
if (split[0].Equals("CAT")
cats.Add(s);
else if (split[0].Equals("HORSE")
horses.Add(s);
// ...
}
But I would prefer the first one.
Algorithmically, I'd do the following:
Parse out all unique prefixes by using the "_" as your delimeter.
Loop through your list of prefixes.
2a. Retrieve any values that have your prefix (loop/find/regex/depends on structure)
2b. Place retrieved values in a List.
2c. Sort list.
Output your results, or do what you need with your collections.
You can order the list up front and sort by prefix:
string[] input = new string[] {"DOG_BOB","CAT_ROB","DOG_DANNY","MOUSE_MICKEY","DOG_STEVE","HORSE_NEIGH","CAT_RUDE","HORSE_BOO","MOUSE_STUPID"};
string[] sortedInput = input.OrderBy(x => x).ToArray();
var distinctSortedPrefixes = sortedInput.Select(item => item.Split('_')[0]).Distinct().ToArray();
Dictionary<string, string[]> orderedByPrefix = new Dictionary<string, string[]>();
for (int prefixIndex = 0; prefixIndex < distinctSortedPrefixes.Length; prefixIndex++)
{
string prefix = distinctSortedPrefixes[prefixIndex];
var group = input.Where(item => item.StartsWith(prefix)).ToArray();
orderedByPrefix.Add(prefix, group);
}
With LINQ, using something like
names.GroupBy(s => s.Substring(0, s.IndexOf("_"))) // group by prefix
.Select(g => string.Join(",", g)) // join each group with commas
.ToList(); // take the results
See it in action (some extra .ToArray() calls included for .NET 3.0 compatibility)
This LINQ expression does what you want.
var result = data.GroupBy(data.Split('_')[0])
.Select(group => String.Join(", ", group))
.ToList();
For a list of lists of strings use this expression.
var result = data.GroupBy(data.Split('_')[0])
.Select(group => group.ToList())
.ToList();

Categories

Resources