C# equivalent to Javascript "push" - c#

I'm trying to convert this code over to C# and was wondering what is the equivalent to Javascript's "Array.push"?
Here's a few lines of the code i'm converting:
var macroInit1, macroInit2;
var macroSteps = new Array();
var i, step;
macroInit1 = "Random String";
macroInit2 = "Random String two";
macroSteps.push(macroInit1 + "another random string");
macroSteps.push(macroInit2 + "The last random string");
for (i=0; i<10; i++)
{
for (step = 0; step < macroSteps.length; step++)
{
// Do some stuff
}
}

You could use a List<string>:
var macroInit1 = "Random String";
var macroInit2 = "Random String two";
var macroSteps = new List<string>();
macroSteps.Add(macroInit1 + "another random string");
macroSteps.Add(macroInit2 + "The last random string");
for (int i = 0; i < 10; i++)
{
for (int step = 0; step < macroSteps.Count; step++)
{
}
}
Of course this code looks extremely ugly in C#. Depending on what manipulations you are performing on those strings you could take advantage of the LINQ features built into C# to convert it into a one-liner and avoid writing all those imperative loops.
This is to say that when converting source code from one language to another it's not a matter of simply searching for the equivalent data type, etc... You could also take advantage of what the target language has to offer.

You can replace that either with
List<string> macroSteps for a type-safe list-of-string
or
ArrayList macroSteps. for a flexible list-of-object
or
Stack<string> macroSteps. It has .Push() and .Pop() like in JS.

It can be much more clean, declarative and nice in C#, for example:
//In .NET both lists and arraus implement IList interface, so we don't care what's behind
//A parameter is just a sequence, again, we just enumerate through
//and don't care if you put array or list or whatever, any enumerable
public static IList<string> GenerateMacroStuff(IEnumerable<string> macroInits) {
{
return macroInits
.Select(x => x + "some random string or function returns that") //your re-initialization
.Select(x => YourDoSomeStuff(x)) //what you had in your foreach
.ToArray();
}
And it can be used then:
var myInits = new[] {"Some init value", "Some init value 2", "Another Value 3"};
var myMacroStuff = GetMacroStuff(myInits); //here is an array of what we need
BTW, we can suggest you a solution how to "do stuff" properly and nicely if you just describe what you want, not just show us a code we don't have any clue how to use and ask how to translate it literally.
Because a literal translation can be so unnatural and ugly in .NET world, and you will have to maintain this ugliness... We don't want you to be in this position :)

Related

how to convert a String list into a String array then converting it into an int array then counting the total sum of the numbers in the array?

So I am so fresh into the world of programming, starting new, I decided to start messing around in C# to create simple apps from ideas that come to mind, with this little app, I'm trying to have multiple TextBoxes named d1,d2,d3,d4,etc... the user inserts numbers into the textboxes then clicks button1, which begins the process in the code below creating a new list which contains all of the values of the textboxes and then the list is converted to an array and the array is then converted into an int array, etc....
BUT, when starting the application and I add values to the textboxes and then click button1, it shows 2 error like shows in the //gray code line below
Please help.
private void button1_Click(object sender, EventArgs e)
{
List<string> dodo = new List<string>();
dodo.Add(d1.Text); dodo.Add(d2.Text); dodo.Add(d3.Text); dodo.Add(d4.Text); dodo.Add(d5.Text);
dodo.Add(d6.Text); dodo.Add(d7.Text); dodo.Add(d8.Text); dodo.Add(d9.Text); dodo.Add(d10.Text);
dodo.Add(d11.Text); dodo.Add(d12.Text); dodo.Add(d13.Text); dodo.Add(d14.Text); dodo.Add(d15.Text);
dodo.Add(d16.Text); dodo.Add(d17.Text); dodo.Add(d18.Text); dodo.Add(d19.Text); dodo.Add(d20.Text);
foreach(string numb in dodo)
{
if (numb == "")
numb = "0"; //numb word has a red underline
}
string[] terms = dodo.ToArray();
int[] valv = {};
int x = 0;
for(int i=0;i<=19;i++)
{
valv[i] = int.Parse(terms[i]); //the ; in the end has a red underline and shows "FormatException was unhandled" error
i++;
x = x + valv[i];
}
string myString;
myString = x.ToString();
Result1.Text = myString;
}
you can't change the iteration variable which is numb in your case. Please change in the List container instead
List<string> dodo = new List<string>();
dodo.Add(d1.Text); dodo.Add(d2.Text); dodo.Add(d3.Text); dodo.Add(d4.Text); dodo.Add(d5.Text);
dodo.Add(d6.Text); dodo.Add(d7.Text); dodo.Add(d8.Text); dodo.Add(d9.Text); dodo.Add(d10.Text);
dodo.Add(d11.Text); dodo.Add(d12.Text); dodo.Add(d13.Text); dodo.Add(d14.Text); dodo.Add(d15.Text);
dodo.Add(d16.Text); dodo.Add(d17.Text); dodo.Add(d18.Text); dodo.Add(d19.Text); dodo.Add(d20.Text);
int k = 0;
foreach (string numb in dodo)
{
if (numb == "")
{
//numb = "0"; //numb word has a red underline
dodo[k] = "0";
}
k++;
}
Now your code on parsing into integer won't give any runtime error.
The first line "tells" you that you are not able to assign a new value to the variable which is used as a foreach iteration variable.
The second line, "tells" you that you have string value which is not able to be parsed correctly (e.g. user put string which is not a number). To avoid this you can use Int32.TryParse method instead, which will safely try to parse the given string.
The best and easiest way to achieve what you need is using LINQ methods, here is the example based on few things/assumptions:
Since you are converting empty strings into zeros, you could simply skip those entries from counting
To avoid FormatException, you should use TryParse method instead. Since TryParse method will safely parse the given string, you don't even have to filter empty strings at all (they will be skipped). However, I deliberately left filtering part, to get you a better overview of a solution.
You can use list initializer to make list initialization more readable
Solution:
List<string> dodo = new List<string>()
{
d1.Text, d2.Text //...others
};
int sum = dodo
.Where(item => !String.IsNullOrEmpty(item))
.Sum(item =>
{
if (Int32.TryParse(item, out int parsedItem))
{
return parsedItem;
}
return 0;
});
You can get more familiar with LINQ and used methods on following link

Replace character at specific index in List<string>, but indexer is read only [duplicate]

This question already has answers here:
Is there an easy way to change a char in a string in C#?
(8 answers)
Closed 5 years ago.
This is kind of a basic question, but I learned programming in C++ and am just transitioning to C#, so my ignorance of the C# methods are getting in my way.
A client has given me a few fixed length files and they want the 484th character of every odd numbered record, skipping the first one (3, 5, 7, etc...) changed from a space to a 0. In my mind, I should be able to do something like the below:
static void Main(string[] args)
{
List<string> allLines = System.IO.File.ReadAllLines(#"C:\...").ToList();
foreach(string line in allLines)
{
//odd numbered logic here
line[483] = '0';
}
...
//write to new file
}
However, the property or indexer cannot be assigned to because it is read only. All my reading says that I have not set a setter for the variable, and I have tried what was shown at this SO article, but I am doing something wrong every time. Should what is shown in that article work? Should I do something else?
You cannot modify C# strings directly, because they are immutable. You can convert strings to char[], modify it, then make a string again, and write it to file:
File.WriteAllLines(
#"c:\newfile.txt"
, File.ReadAllLines(#"C:\...").Select((s, index) => {
if (index % 2 = 0) {
return s; // Even strings do not change
}
var chars = s.ToCharArray();
chars[483] = '0';
return new string(chars);
})
);
Since strings are immutable, you can't modify a single character by treating it as a char[] and then modify a character at a specific index. However, you can "modify" it by assigning it to a new string.
We can use the Substring() method to return any part of the original string. Combining this with some concatenation, we can take the first part of the string (up to the character you want to replace), add the new character, and then add the rest of the original string.
Also, since we can't directly modify the items in a collection being iterated over in a foreach loop, we can switch your loop to a for loop instead. Now we can access each line by index, and can modify them on the fly:
for(int i = 0; i < allLines.Length; i++)
{
if (allLines[i].Length > 483)
{
allLines[i] = allLines[i].Substring(0, 483) + "0" + allLines[i].Substring(484);
}
}
It's possible that, depending on how many lines you're processing and how many in-line concatenations you end up doing, there is some chance that using a StringBuilder instead of concatenation will perform better. Here is an alternate way to do this using a StringBuilder. I'll leave the perf measuring to you...
var sb = new StringBuilder();
for (int i = 0; i < allLines.Length; i++)
{
if (allLines[i].Length > 483)
{
sb.Clear();
sb.Append(allLines[i].Substring(0, 483));
sb.Append("0");
sb.Append(allLines[i].Substring(484));
allLines[i] = sb.ToString();
}
}
The first item after the foreach (string line in this case) is a local variable that has no scope outside the loop - that’s why you can’t assign a value to it. Try using a regular for loop instead.
Purpose of for each is meant to iterate over a container. It's read only in nature. You should use regular for loop. It will work.
static void Main(string[] args)
{
List<string> allLines = System.IO.File.ReadAllLines(#"C:\...").ToList();
for (int i=0;i<=allLines.Length;++i)
{
if (allLines[i].Length > 483)
{
allLines[i] = allLines[i].Substring(0, 483) + "0";
}
}
...
//write to new file
}

Remove part of a string from List<string>

I have a List<string>, the string part representing filenames that I need to filter out: anything that comes before the character '&' included must be erased.
List<string> zippedTransactions = new List<string>();
zippedTransactions.Add("33396&20151007112154000549659S03333396SUMMARIES.PDF");
zippedTransactions.Add("33395&20151007112400000549659S03333395SUMMARIES.PDF");
zippedTransactions.Add("33397&20151007112555000549659S03333397SUMMARIES.PDF");
// desired output:
// "20151007112154000549659S03333396SUMMARIES.PDF";
// "20151007112400000549659S03333395SUMMARIES.PDF";
// "20151007112555000549659S03333397SUMMARIES.PDF"
NOTE: I don't want to give it the classic iterative-style look, since C# provides for plentiful of functional interfaces to interact with this sort of data structure, I want to start using it.
Here is one Linq approach with RegEx
Transactions = Transactions.Select(x => Regex.Replace(x, ".*&", string.Empty)).ToList();
That's more fault tolerant compared to Split('&')[1] in case there is no & in your filename
Try this
for (int i = 0; i < zippedTransactions.Count; i++)
{
zippedTransactions[i] = zippedTransactions[i].Split('&')[1];
}
If you happen to have visual studio, and a version that supports C# Interactive, I suggest you try this.
> zippedTransactions = new List<string>() {
"33396&20151007112154000549659S03333396SUMMARIES.PDF",
"33395&20151007112400000549659S03333395SUMMARIES.PDF",
"33397&20151007112555000549659S03333397SUMMARIES.PDF"
};
>
> zippedTransactions.Select(dirname => dirname.Split('&')[1])
Enumerable.WhereSelectListIterator<string, string> { "20151007112154000549659S03333396SUMMARIES.PDF", "20151007112400000549659S03333395SUMMARIES.PDF", "20151007112555000549659S03333397SUMMARIES.PDF" }
>
And even if you don't, you can get an idea of what's happening just by looking at the code.
The WhereSelectListIterator is a data structure holding the logic you intend to execute on the data structure. It is evaluated (read: the loop actually happens) only when you consume it (for example, calling .ToList() at the end).
This code will only take the second element coming after splitting the string on '&', so you might wanna generalize it or tune it for your requirements.
Use string.Split to split the string at the desired character and retrieve the portion that you want:
foreach (var item in zippedTransactions)
{
string[] result = item.Split('&');
Console.WriteLine(result[1]);
}
You can use the string.IndexOf function to find the location of a character in the string and then use string.Remove to remove the characters up to that point:
for(int i =0; i < zippedTransactions.Count; i++)
{
int count = zippedTransactions[i].IndexOf("&") + 1;
zippedTransactions[i] = zippedTransactions[i].Remove(0, count);
}
following code will help you
for (int i = 0; i < zippedTransactions.Count; i++)
{
string[] result = zippedTransactions[i].Split('&');
zippedTransactions[i] = result[result.Length-1];
}

C# Loop Through An Array

I am completely new to C#. I am trying to loop through a short array, where the string elements in the array are placed at the end of a website search. The code:
int n = 1;
string[] s = {"firstitem","seconditem","thirditem"}
int x = s.Max(); // note, from my research this should return the maximum value in the array, but this is the first error
x = x + 1
while (n < x)
{
System.Diagnostics.Process.Start("www.website.com/" + b[0]);
b[]++; // this also generates an error "identifier expected"
}
My coding, logic or both are wrong. Based on what I've read, I should be able to get the maximum value in an array (as an int), then add to the arrays value while a WHILE loop adds each value in the array at the end of the website (and then stops). Note, that on the first error, I tried coding it differently, like the below:
int x = Convert.ToInt32(s.Max);
However, it generates an overload error. If I'm reading things correctly, MAX should find the maximum value in a sequence.
foreach(var str in s)
{
System.Diagnostics.Process.Start("www.website.com/" + str);
}
You have a collection of strings. The largest string is still a string, not an int. Since s.Max() is a string, and you're assinging it to a variable of type int: int x = s.Max(); the compiler (correctly) informs you that the types do not match. You need to convert that string to an int. Since, looking at your data, they aren't integers, and I see no sensible way of converting those strings into integers, I see no reasonable solution. What integer should "firstitem" be?
If you just want to execute some code for each item in the array then use one of these patterns:
foreach(string item in s)
{
System.Diagnostics.Process.Start("www.website.com/" + item);
}
or
for(int i = 0; i < s.Length; i++)
{
System.Diagnostics.Process.Start("www.website.com/" + s[i]);
}
You're missing a couple of semi-colons
x should presumably be the Length of the array, not the largest value in it
You need to increment x inside of your loop - at the end of it, not outside of it
You should actually be incrementing n, not x
n should be starting at 0, not at 1
Inside the loop you're using b[0] where you probably want to use b[n]
I'm no C++ guru, but I have no idea what b[]++ might mean
As other answers have mentioned, you may want to use a for or foreach instead of a while.
Make an effort to go through some introductory tutorials. Trial and error can be a useful tool, but there's no need to fall back on that when learning the very basics
Following is an image to point out what are the errors of your code:
After the correction, it would be:
int n=1;
string[] s= { "firstitem", "seconditem", "thirditem" };
int x=s.Length;
while(n<x) {
System.Diagnostics.Process.Start("www.website.com/"+s[n]);
n++; // or ++n
}
And we can make it more semantic:
var items=new[] { "firstitem", "seconditem", "thirditem" };
for(int index=1, count=items.Length; index<count; ++index)
Process.Start("www.website.com/"+items[index]);
If the starting order doesn't matter, and we can use foreach instead, and we can use Linq to make the code even simpler:
var list=(new[] { "firstitem", "seconditem", "thirditem" }).ToList();
list.ForEach(item => Process.Start("www.website.com/"+item));
and we might quite often write in another form:
foreach(var item in new[] { "firstitem", "seconditem", "thirditem" })
Process.Start("www.website.com/"+item);
from the sample
var processList = (new string[]{"firstitem","seconditem","thirditem"})
.Select(s => Process.Start("www.website.com/" + s))
.ToList();
and here is a test version that outputs to console
(new string[] { "firstitem", "seconditem", "thirditem" })
.Select(s => { Console.WriteLine(#"www.website.com/" + s); return s; })
.ToList();
note: Select requires a return type and the .ToList() enforces evaluation.

How can i construct a variable name in code from a string?

I have a number of variables named test1....test10 they are all declared as a string.
what I want to do is access them from inside a loop using the loop counter something like this:
string test1;
//...
string test10;
for (int i = 1; i < 10; i++)
{
test + i.ToString() = "some text";
}
any idea how I could do this?
this is a WPF .net 4 windows App.
Simple answer: don't have 10 variables, have one variable which is a collection:
List<string> test = new List<string>();
for (int i = 1; i < 10; i++)
{
test.Add("some text");
}
Having lots of variables which logically form a collection is a design smell.
(If you really have to do this, you could use reflection. But please don't.)
You simply can't, use a List or a String-Array for this purpose.
List
List<String> myStrings = new List<String>();
for (Int32 i = 0; i < 10; i++)
{
myStrings.Add("some text");
}
String-Array
String[] myStrings = new String[10];
for (Int32 i = 0; i < myStrings.length; i++)
{
myStrings[i] = "some text";
}
Try adding them to an array of string[] or simply create a List<string> list = new List<string>();.
With the list, you can iterate easily.
This is not really possible, unless you use the dynamic keyword, and then you will get a property instead of a true variable. Take a look at ExpandoObject, it will allow you to add properties based on a string variable.
In your case, as other have said, you really should use a List<string>
For something as simple as 10 items, an array is the best way to go. Fast and easy.

Categories

Resources