Replace every other of a certain char in a string - c#

I have searched a lot to find a solution to this, but could not find anything. I do however suspect that it is because I don't know what to search for.
First, I have a string that I convert to an array. The string will be formatted like so:
"99.28099822998047,68.375 118.30699729919434,57.625 126.49999713897705,37.875 113.94499683380127,11.048999786376953 96.00499725341797,8.5"
I create the array with the following code:
public static Array StringToArray(string String)
{
var list = new List<string>();
string[] Coords = String.Split(' ', ',');
foreach (string Coord in Coords)
{
list.Add(Coord);
}
var array = list.ToArray();
return array;
}
Now my problem is; I am trying to find a way to convert it back into a string, with the same formatting. So, I could create a string simply using:
public static String ArrayToString(Array array)
{
string String = string.Join(",", array);
return String;
}
and then hopefully replace every 2nd "," with a space (" "). Is this possible? Or are there a whole other way you would do this?
Thank you in advance! I hope my question makes sense.

There is no built-in way of doing what you need. However, it's pretty trivial to achieve what it is you need e.g.
public static string[] StringToArray(string str)
{
return str.Replace(" ", ",").Split(',');
}
public static string ArrayToString(string[] array)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= array.Length-1; i++)
{
sb.AppendFormat(i % 2 != 0 ? "{0} " : "{0},", array[i]);
}
return sb.ToString();
}

If those are pairs of coordinates, you can start by parsing them like pairs, not like separate numbers:
public static IEnumerable<string[]> ParseCoordinates(string input)
{
return input.Split(' ').Select(vector => vector.Split(','));
}
It is easier then to reconstruct the original string:
public static string PrintCoordinates(IEnumerable<string[]> coords)
{
return String.Join(" ", coords.Select(vector => String.Join(",", vector)));
}
But if you absolutely need to have your data in a flat structure like array, it is then possible to convert it to a more structured format:
public static IEnumerable<string[]> Pairwise(string[] coords)
{
coords.Zip(coords.Skip(1), (coord1, coord2) => new[] { coord1, coord2 });
}
You then can use this method in conjunction with PrintCoordinates to reconstruct your initial string.

Here is a route to do it. I don't think other solutions were removing last comma or space. I also include a test.
public static String ArrayToString(Array array)
{
var useComma = true;
var stringBuilder = new StringBuilder();
foreach (var value in array)
{
if (useComma)
{
stringBuilder.AppendFormat("{0}{1}", value, ",");
}
else
{
stringBuilder.AppendFormat("{0}{1}", value, " ");
}
useComma = !useComma;
}
// Remove last space or comma
stringBuilder.Length = stringBuilder.Length - 1;
return stringBuilder.ToString();
}
[TestMethod]
public void ArrayToStringTest()
{
var expectedStringValue =
"99.28099822998047,68.375 118.30699729919434,57.625 126.49999713897705,37.875 113.94499683380127,11.048999786376953 96.00499725341797,8.5";
var array = new[]
{
"99.28099822998047",
"68.375",
"118.30699729919434",
"57.625",
"126.49999713897705",
"37.875",
"113.94499683380127",
"11.048999786376953",
"96.00499725341797",
"8.5",
};
var actualStringValue = ArrayToString(array);
Assert.AreEqual(expectedStringValue, actualStringValue);
}

Another way of doing it:
string inputString = "1.11,11.3 2.22,12.4 2.55,12.8";
List<string[]> splitted = inputString.Split(' ').Select(a => a.Split(',')).ToList();
string joined = string.Join(" ", splitted.Select(a => string.Join(",",a)).ToArray());
"splitted" list will look like this:
1.11 11.3
2.22 12.4
2.55 12.8
"joined" string is the same as "inputString"

Here's another approach to this problem.
public static string ArrayToString(string[] array)
{
Debug.Assert(array.Length % 2 == 0, "Array is not dividable by two.");
// Group all coordinates as pairs of two.
int index = 0;
var coordinates = from item in array
group item by index++ / 2
into pair
select pair;
// Format each coordinate pair with a comma.
var formattedCoordinates = coordinates.Select(i => string.Join(",", i));
// Now concatinate all the pairs with a space.
return string.Join(" ", formattedCoordinates);
}
And a simple demonstration:
public static void A_Simple_Test()
{
string expected = "1,2 3,4";
string[] array = new string[] { "1", "2", "3", "4" };
Debug.Assert(expected == ArrayToString(array));
}

Related

How can I split a string to store contents in two different arrays in c#?

The string I want to split is an array of strings.
the array contains strings like:
G1,Active
G2,Inactive
G3,Inactive
.
.
G24,Active
Now I want to store the G's in an array, and Active or Inactive in a different array. So far I have tried this which has successfully store all the G's part but I have lost the other part. I used Split fucntion but did not work so I have tried this.
int i = 0;
for(i = 0; i <= grids.Length; i++)
{
string temp = grids[i];
temp = temp.Replace(",", " ");
if (temp.Contains(' '))
{
int index = temp.IndexOf(' ');
grids[i] = temp.Substring(0, index);
}
//System.Console.WriteLine(temp);
}
Please help me how to achieve this goal. I am new to C#.
If I understand the problem correctly - we have an array of strings Eg:
arrayOfStrings[24] =
{
"G1,Active",
"G2,Inactive",
"G3,Active",
...
"G24,Active"
}
Now we want to split each item and store the g part in one array and the status into another.
Working with arrays the solution is to - traverse the arrayOfStrings.
Per each item in the arrayOfStrings we split it by ',' separator.
The Split operation will return another array of two elements the g part and the status - which will be stored respectively into distinct arrays (gArray and statusArray) for later retrieval. Those arrays will have a 1-to-1 relation.
Here is my implementation:
static string[] LoadArray()
{
return new string[]
{
"G1,Active",
"G2,Inactive",
"G3,Active",
"G4,Active",
"G5,Active",
"G6,Inactive",
"G7,Active",
"G8,Active",
"G9,Active",
"G10,Active",
"G11,Inactive",
"G12,Active",
"G13,Active",
"G14,Inactive",
"G15,Active",
"G16,Inactive",
"G17,Active",
"G18,Active",
"G19,Inactive",
"G20,Active",
"G21,Inactive",
"G22,Active",
"G23,Inactive",
"G24,Active"
};
}
static void Main(string[] args)
{
string[] myarrayOfStrings = LoadArray();
string[] gArray = new string[24];
string[] statusArray = new string[24];
int index = 0;
foreach (var item in myarrayOfStrings)
{
var arraySplit = item.Split(',');
gArray[index] = arraySplit[0];
statusArray[index] = arraySplit[1];
index++;
}
for (int i = 0; i < gArray.Length; i++)
{
Console.WriteLine("{0} has status : {1}", gArray[i] , statusArray[i]);
}
Console.ReadLine();
}
seems like you have a list of Gxx,Active my recomendation is first of all you split the string based on the space, which will give you the array previoulsy mentioned doing the next:
string text = "G1,Active G2,Inactive G3,Inactive G24,Active";
string[] splitedGItems = text.Split(" ");
So, now you have an array, and I strongly recommend you to use an object/Tuple/Dictionary depends of what suits you more in the entire scenario. for now i will use Dictionary as it seems to be key-value
Dictionary<string, string> GxListActiveInactive = new Dictionary<string, string>();
foreach(var singleGItems in splitedGItems)
{
string[] definition = singleGItems.Split(",");
GxListActiveInactive.Add(definition[0], definition[1]);
}
What im achiving in this code is create a collection which is key-value, now you have to search the G24 manually doing the next
string G24Value = GxListActiveInactive.FirstOrDefault(a => a.Key == "G24").Value;
just do it :
var splitedArray = YourStringArray.ToDictionary(x=>x.Split(',')[0],x=>x.Split(',')[1]);
var gArray = splitedArray.Keys;
var activeInactiveArray = splitedArray.Values;
I hope it will be useful
You can divide the string using Split; the first part should be the G's, while the second part will be "Active" or "Inactive".
int i;
string[] temp, activity = new string[grids.Length];
for(i = 0; i <= grids.Length; i++)
{
temp = grids[i].Split(',');
grids[i] = temp[0];
activity[i] = temp[1];
}

add text/numbers in string builder based on length of string builder

I wanted to add the numbers (1,2,3) in my string builder before displaying.
If the string builder contains 2- it should have output like this 1) Line text 2) line text and so on
StringBuilder abc = new StringBuilder();
abc.Append("Hi.");
Fun(2, abc);
void Fun(int i, StringBuilder abc)
{
if (i>0)
abc.Append("its me.");
}
// Add some code here to check like if(abc.length>0) // we need to append 1,2,3... to the lines in abc
Console.WriteLine(abc.ToString());
i need the output like
1)Hi. 2) its me.
You can encapsulate logic in different class and use StringBuilder under the hood.
public class ExtendedStringBuilder
{
private StringBuilder _sb;
private int _callNumber;
public ExtendedStringBuilder()
{
_sb = new StringBuilder();
_callNumber = 0;
}
public void Append(string nextString)
{
_sb.AppendFormat("{0} {1}", ++_callNumber, nextString);
}
public override string ToString()
{
return _sb.ToString();
}
}
In this case you do not need to store int value. This is sample:
static void Main(string[] args)
{
var esb = new ExtendedStringBuilder();
esb.Append("Hi.");
esb.Append("its me.");
Console.WriteLine(esb.ToString());
Console.ReadLine();
}
It would be incredibly hard to do it with StringBuilder as index parsing will be ridiculously difficult. I've used List<string> to achieve the same.
List<string> list = new List<string>();
list.Add("Hi");
list.Add("Its me!");
string s = String.Join(" ", list.Select(x => (list.IndexOf(x) + 1).ToString() + ")" + x));
Console.WriteLine(s);
Which gives the output as
1)Hi 2)Its me!
I suggest using Linq, put all the items ("Hi.", "its me.") and get rid of StringBuilder:
using System.Linq;
...
// Or List<string>
string[] items = new string[] {
"Hi.",
"its me."
};
string result = string.Join(" ", items
.Select((item, index) => $"{index + 1}){item}"));
Your code modified (List<string> instead of StringBuilder)
List<string> abc = new List<string>(); // List<string>, not StringBuider
abc.Add("Hi.");
Fun(2, abc);
...
void Fun(int i, IList<string> abc) {
if (abc.Any())
abc.Add("its me.");
}
...
Console.WriteLine(string.Join(" ", abc
.Select((item, index) => $"{index + 1}){item}")));

Removing matching characters between two strings

I want to remove the characters which are matching between the two given strings. Eg.
string str1 = "Abbbccd";
string str2 = "Ebbd";
From these two strings I want the output as:
"Abcc", only those many matching characters should be removed from str1,which are present in str2.
I tried the following code:
public string Sub(string str1, string str2)
{
char[] arr1 = str1.ToCharArray();
char[] arr2 = str2.ToCharArray();
char[] arrDifference = arr1.Except(arr2).ToArray();
string final = new string(arrDifference);
return final;
}
With this code I get the output as "Ac". It removes all the matching characters between two arrays and stores 'c' only once.
First create this helper method:
IEnumerable<Tuple<char, int>> IndexDistinct(IEnumerable<char> source)
{
var D = new Dictionary<char, int>();
foreach (var c in source)
{
D[c] = D.ContainsKey(c) ? (D[c] + 1) : 0;
yield return Tuple.Create(c, D[c]);
}
}
It converts a string "aabcccd" to [(a,0),(a,1),(b,0),(c,0),(c,1),(c,2),(d,0)]. The idea is to make every character distinct by adding a counting index on equal characters.
Then modify your proposed function like this:
string Sub(string str1, string str2)
{
return new string(
IndexDistinct(str1)
.Except(IndexDistinct(str2))
.Select(x => x.Item1)
.ToArray());
}
Now that you are doing Except on Tuple<char, int> instead of just char, you should get the behavior you specified.
You can do it with lists as well:
List<char> one = new List<char>("Abbbccd".ToCharArray());
List<char> two = new List<char>("Ebbd".ToCharArray());
foreach (char c in two) {
try { one.RemoveAt(one.IndexOf(c)); } catch { }
}
string result = new string(one.ToArray());
Use C#'s string commands to modify the string.
public string testmethod(string str1, string str2)
{
string result = str1;
foreach (char character in str2.ToCharArray())
{
result = result.Replace(character.ToString(), "");
}
return result;
}

Need help on a simple string sort method from a string array

seriously need some guideline on string sorting methodology. Perhaps, if able to provide some sample code would be a great help. This is not a homework. I would need this sorting method for concurrently checking multiple channel names and feed the channel accordingly based on the sort name/string result.
Firstly I would have the string array pattern something like below:
string[] strList1 = new string[] {"TDC1ABF", "TDC1ABI", "TDC1ABO" };
string[] strList2 = new string[] {"TDC2ABF", "TDC2ABI", "TDC2ABO"};
string[] strList3 = new string[] {"TDC3ABF", "TDC3ABO","TDC3ABI"}; //2nd and 3rd element are swapped
I would like to received a string[] result like below:
//result1 = "TDC1ABF , TDC2ABF, TDC3ABF"
//result2 = "TDC1ABI , TDC2ABI, TDC3ABI"
//result3 = "TDC1ABO , TDC2ABO, TDC3ABO"
Ok, here is my idea of doing the sorting.
First, each of the strList sort keyword *ABF.
Then, put all the strings with *ABF into result array.
Finally do Order sort to have the string array align into TDC1ABF, TDC2ABF, TDC3ABF accordingly.
Do the same thing for the other string array inside a loop.
So, my problem is.. how to search *ABF within a string inside a string array?
static void Main()
{
var strList1 = new[] { "TDC1ABF", "TDC1ABI", "TDC1ABO" };
var strList2 = new[] { "TDC2ABF", "TDC2ABI", "TDC2ABO" };
var strList3 = new[] { "TDC3ABF", "TDC3ABO", "TDC3ABI" };
var allItems = strList1.Concat(strList2).Concat(strList3);
var abfItems = allItems.Where(item => item.ToUpper().EndsWith("ABF"))
.OrderBy(item => item);
var abiItems = allItems.Where(item => item.ToUpper().EndsWith("ABI"))
.OrderBy(item => item);
var aboItems = allItems.Where(item => item.ToUpper().EndsWith("ABO"))
.OrderBy(item => item);
}
If you do something like this then you can compare all the sums and arrange them in order. The lower sums are the ones closer to 1st and the higher are the ones that are farther down.
static void Main(string[] args)
{
string[] strList1 = new string[] { "TDC1ABF", "TDC1ABI", "TDC1ABO" };
string[] strList2 = new string[] { "TDC2ABF", "TDC2ABI", "TDC2ABO" };
string[] strList3 = new string[] { "TDC3ABF", "TDC3ABO", "TDC3ABI" };
arrange(strList1);
arrange(strList2);
arrange(strList3);
}
public static void arrange(string[] list)
{
Console.WriteLine("OUT OF ORDER");
foreach (string item in list)
{
Console.WriteLine(item);
}
Console.WriteLine();
for (int x = 0; x < list.Length - 1; x++)
{
char[] temp = list[x].ToCharArray();
char[] temp1 = list[x + 1].ToCharArray();
int sum = 0;
foreach (char letter in temp)
{
sum += (int)letter; //This adds the ASCII value of each char
}
int sum2 = 0;
foreach (char letter in temp1)
{
sum2 += (int)letter; //This adds the ASCII value of each char
}
if (sum > sum2)
{
string swap1 = list[x];
list[x] = list[x + 1];
list[x + 1] = swap1;
}
}
Console.WriteLine("IN ORDER");
foreach (string item in list)
{
Console.WriteLine(item);
}
Console.WriteLine();
Console.ReadLine();
}
If the arrays are guaranteed to have as many elements as there are arrays then you could sort the individual arrays first, dump the sorted arrays into an nxn array and then transpose the matrix.

How to delete last character in a string in C#?

Building a string for post request in the following way,
var itemsToAdd = sl.SelProds.ToList();
if (sl.SelProds.Count() != 0)
{
foreach (var item in itemsToAdd)
{
paramstr = paramstr + string.Format("productID={0}&", item.prodID.ToString());
}
}
after I get resulting paramstr, I need to delete last character & in it
How to delete last character in a string using C#?
Personally I would go with Rob's suggestion, but if you want to remove one (or more) specific trailing character(s) you can use TrimEnd. E.g.
paramstr = paramstr.TrimEnd('&');
build it with string.Join instead:
var parameters = sl.SelProds.Select(x=>"productID="+x.prodID).ToArray();
paramstr = string.Join("&", parameters);
string.Join takes a seperator ("&") and and array of strings (parameters), and inserts the seperator between each element of the array.
string source;
// source gets initialized
string dest;
if (source.Length > 0)
{
dest = source.Substring(0, source.Length - 1);
}
Try this:
paramstr.Remove((paramstr.Length-1),1);
I would just not add it in the first place:
var sb = new StringBuilder();
bool first = true;
foreach (var foo in items) {
if (first)
first = false;
else
sb.Append('&');
// for example:
var escapedValue = System.Web.HttpUtility.UrlEncode(foo);
sb.Append(key).Append('=').Append(escapedValue);
}
var s = sb.ToString();
string str="This is test string.";
str=str.Remove(str.Length-1);
It's better if you use string.Join.
class Product
{
public int ProductID { get; set; }
}
static void Main(string[] args)
{
List<Product> products = new List<Product>()
{
new Product { ProductID = 1 },
new Product { ProductID = 2 },
new Product { ProductID = 3 }
};
string theURL = string.Join("&", products.Select(p => string.Format("productID={0}", p.ProductID)));
Console.WriteLine(theURL);
}
It's good practice to use a StringBuilder when concatenating a lot of strings and you can then use the Remove method to get rid of the final character.
StringBuilder paramBuilder = new StringBuilder();
foreach (var item in itemsToAdd)
{
paramBuilder.AppendFormat(("productID={0}&", item.prodID.ToString());
}
if (paramBuilder.Length > 1)
paramBuilder.Remove(paramBuilder.Length-1, 1);
string s = paramBuilder.ToString();
paramstr.Remove((paramstr.Length-1),1);
This does work to remove a single character from the end of a string. But if I use it to remove, say, 4 characters, this doesn't work:
paramstr.Remove((paramstr.Length-4),1);
As an alternative, I have used this approach instead:
DateFrom = DateFrom.Substring(0, DateFrom.Length-4);
Add a StringBuilder extension method.
public static StringBuilder RemoveLast(this StringBuilder sb, string value)
{
if(sb.Length < 1) return sb;
sb.Remove(sb.ToString().LastIndexOf(value), value.Length);
return sb;
}
then use:
yourStringBuilder.RemoveLast(",");

Categories