c# basic formatting question - c#

If I wanted to swap out part of a statement with a variable i.e.
tempCube.transform.parent = row(var would need to go here ie an int that is iterated with a for loop).transform;
How would I write this. Sorry for the really basic question, I have been using other languages too long and now I have gone back to c# I have almost forgotten everything I had learned.
"(i)" is the bit I want to swap out with a variable
eg
for(int i = 1; i <= 3; i++){ print row*(i)*.transform; }
Console:
(1,2,3)
(2,3,4)
(4,5,6)

You mean like:-
row1.transform;
row2.transform;
row3.transform;
...
If so, no, you can't replace that text at runtime. You should use a collection. Ideally make an IEnumerable out of them and use foreach:-
foreach (var x in new { row1, row2, row3 ... })
{
x.transform;
}

I am not sure what you mean, i hope you want to specify the index, is this what you are looking for (index is the int you mentioned)
tempCube.transform.parent = row[index].transform;

Related

How to create arrays with different names in C#?

I'm currently working on a game (console application) with 25 Chunks, that are 5x5. All Chunks are in a List(5x5) witch is the Level in the end.
I do not want to declare all arrays. I would like to write a method in witch the arrays will be declared but with changing names.
For example:
- ac_Array_1
- ac_Array_2
static void Level()
{
List<char[,]> ol_Level = new List<char[,]>();
}
static void Spielblock()
{
int i_Stelle = 1;
string s_ArrayName = "ac_Chunk_" + i_Stelle;
i_Stelle++;
char[,] /*NAME*/ = new char[5, 5];
}
Try something like this:
int numOfLevels = 5;
Dictionary<string, char[,]> ol_Level = Enumerable
.Range(1, numOfLevels)
.ToDictionary(k => $"ac_Chunk_{k}", v => new char[5,5]);
ac_Chunk = ol_Level["ac_Chunk_1"];//char[5,5]
for (int i_Row = 0; i_Row < ac_Chunk.getLength(0); i_Row++)
{
for (int i_column = 0; i_column < ac_Chunk.getLength(1); i_column++)
{
ac_Chunk[i_Row, i_column] = '#';
}
}
...
levels:
ac_Chunk_1, ac_Chunk_2, ac_Chunk_3, ac_Chunk_4, ac_Chunk_5
n.b. using System.Linq and c# 6.0 $ interpolation
To have a dynamic variable name like you are requesting is not a simple thing to accomplish.
Generally, variable names are known at compile time, and the compiler can make optimizations using that information. What you are requesting would keep that from happening.
So the suggestions that you are seeing: create a variable, such as a dictionary, known when compiling and writing the code. Make that variable one that can dynamically expand to contain as many "chunks" as you'd like. And with a Dictionary<string, char[,]> you can even give each of those chunks a name. They won't be individual variable names, but it will let you access them by string/name and iterate through the collection in different ways.
To add a detail to Johnny's answer, at any point you can use
var ac_chunk = ol_Level["ac_Chunk_1"];
if you want to repeatedly access an individual chunk.
Or, even easier, just keep using ol_Level[$"ac_Chunk_{chunkNumber}"]

C# - Compile variable as name/code

Since I couldn't explain very good in my last question and I didn't get an answer that could satisfy me, I decided to open a new one. Straight to the point, what I'm basically trying to do is compiling a variable (the value it holds) as a part of code (and specificly in my case referencing another variable)
Say I have:
int var_1, var_2, var_3 ... var_10;
for (int i = 1; i <= 10; i++)
{
var_%i%=20; //if i is 1, then var_1's value will be set to 20, if i is 2, then var_2's value will be set to 20. So basically this loop sets the value of var_1 .. var_10 to 20
}
I can explain in an even simpler way, if in any case the latter is not clear.
int var_5;
int SomeOtherVar = 5;
var_%SomeOtherVar% = 10; // so var_5 (where 5 is the value of SomeOtherVar) is set to 10
Is this doable and if it is, what's the approach?
No you can't do that, why dont you use an array?
int[] array = new int[3];
for (int i = 0; i < array.Length; ++i)
{
array[i] = 20;
}
Hope it helps.
It's not doable. Use an array instead. The type is int[] but I suggest you go read a tutorial about arrays to understand how to create and use them.
I can't think of a situation where you'd need to do this. If you wish to store values against a consecutive list of numbers, use an array. Otherwise you could use a Dictionary. For example to store "var1" = 20, "var2" = 20 as in your question, you could do this:
Dictionary<string, int> dict = new Dictionary<string, int>();
for (int i = 1; i <= 10; i++)
{
dict.Add("var" + i.ToString(), 20);
}
Some examples of usage:
dict["var1"] // 20
dict["var2"] // 20
dict.ContainsKey("var3") // true
dict.ContainsKey("var99") // false
Note: I'm concatenating the string "var" with the int from the loop just to demonstrate that you can use arbitary strings as keys to store / lookup the values. In this case it's a bit of a strange thing to do, and you'd probably be best sticking to a normal array, but my example shows how a dictionary could work with more complex keys.
If you want to bypass static type checking and you feel like creating some coding horror, you can use ExpandoObject combined with the dynamic keyword. Won't let you set variables in your scope, but will technically let you declare your own ones. Note that in my example I cast it to IDictionary<string, object> because I create its members' names at runtime from a string. What the following method does is create twenty members and assign their values from 0 to 19.
static dynamic SetVariables(IEnumerable<int> range)
{
const string variableName = "var_";
var expandoDictionary = new ExpandoObject() as IDictionary<string, object>;
foreach (var i in range)
expandoDictionary[variableName + i] = i;
return expandoDictionary;
}
You can then access the members easily this way:
var container = SetVariables(Enumerable.Range(0, 20));
var value13 = container.var_13;
Please note that I do not recommend this usage, and I'd stay away from dynamic as much as I can. However, for the sake of problem solving, this can be seen as one unsafe but partial solution.

How do I get the number of listitems that meet certain criteria?

I need for example the number of list-items, that are NOT "".
ATM, I solve it like this:
public int getRealCount()
{
List<string> all = new List<string>(originList);
int maxall = all.Count;
try
{
for (int i = 0; i < maxall; i++)
{
all.Remove("");
}
}
catch { }
return all.Count;
}
No question, performance is pretty bad. I'm lucky it's just a 10-items-list, but on a phone you should avoid such code.
So my question is, how can I improve this code?
One idea was: there could already be a method for that. The econd method would be: that all could be filled with only the items that are not "".
How should I solve this?
Thanks
Sounds like you want:
return originList.Count(x => x != "");
There's no need to create a copy of the collection at all. Note that you'll need using System.Linq; in your using directives at the start of your source code.
(Note that you should not have empty catch blocks like that - it's a terrible idea to suppress exceptions in that way. Only catch exceptions when you either want to really handle them or when you want to rethrow them wrapped as another type. If you must ignore an exception, you should at least log it somewhere.)
If performance is your concern, then you should keep a collection that is only for these items.
If performance is not a big deal, I would suggest you use a Linq query on your collection. The cool thing about Linq is that the search is delayed until you need it.
int nonEmptyItemCount = originList.Count(str => !string.IsNullOrEmpty(str));
You could also do
int nonEmptyItemCount = originList.Count(str => str != "");
You should use LINQ. Install ReSharper, it'll generate it for you.
Also, don't create an int maxall = all.Count and then use it in your for loop.
For mobile apps you shouldn't use unnecessary memory so just use all.Count in the for loop.
You're calling all.remove("") for every item in the list all. Why not just call it once? You're not using i at all in your code...
Why not:
public int getRealCount()
{
List<string> all = new List<string>(originList);
int erased =all.RemoveAll(delegate(string s)
{
return s == "";
});
return all.Count - erased;
}
Update:
Fixed the issue I had. This is without lambda's.

How to get last object from List<> in C# 2.0

I have below condition in my C# 2.0.
There is some VbScript code:
For i = 0 to UBound(components) - 1
If i = UBound(Components) - 1 Then
WriteOut "<div class=""clearBoth""></div>"
End If
Next
Below I am trying to write in C#, please suggest what condition will be written for "If i = UBound(Components) - 1 Then" in c#.
List<tc.ComponentPresentation> cmp = new List<tc.ComponentPresentation>();
foreach (tc.ComponentPresentation cm in cmp)
{
//Here I want to right one condition that
if(this is the last object in "cmp" list)
{
////do something
}
}
Please suggest!!
if (cmp[cmp.Count - 1] == cm)
That should work.
tc.ComponentPresentation lastItem = cmp[cmp.Count - 1];
The simplest approach would be to use the indexer instead:
for (int i = 0; i < cmp.Count; i++)
{
var cm = cmp[i];
if (i == cmp.Count - 1)
{
// Handle the last value differently
}
}
An alternative is to use something like the "smart enumerations" from MiscUtil, which lets you use a foreach loop but still access the "is first", "is last", and "index" for each entry. With C# 3 it's actually somewhat simpler to use than the code in that blog post:
foreach (var entry in SmartEnumerable.Create(cmp))
{
var cm = entry.Value;
if (entry.IsLast)
{
...
}
}
(As an aside, tc is an odd namespace name...)
EDIT: Note that checking whether your current item is equal to the last item in the list is not a reliable indication that you're currently on the last iteration. It will only work if the list contains distinct elements. Both of the approaches above really tell you whether you're on the last iteration, which is what I assumed you wanted.
Try this :
cmp[cmp.Count - 1];
Change the 'foreach' loop into a 'for' loop and use the indexer for the loop to copare to cmp.Length
Why do you need to iterate through the list?
If you want to work with the last element then just use
tc.ComponentPresentation cp = cmp[cmp.Count - 1];
//Do anything with cp here
That's it

how to access a string array outside loop

for (int z = 0; z < alParmValues.Count; z++)
{
//string[] def;
string[] asd = alParmValues[z].ToString().Split(',');//this is of type string.collections and u cant cast it to a arraylist or array
//if (HUTT.clsParameterValues.bCustomObj == false)
string[] def = alMethSign[z].ToString().Substring(alMethSign[z].ToString().IndexOf('(') + 1, alMethSign[z].ToString().IndexOf(')') - (alMethSign[z].ToString().IndexOf('(') + 1)).Split(',');
}
I have to access both the string arrays outside the loop. Is there a better solution to this? I can't use an ArrayList or declare them as public so how can I access them?
To access something outside of a loop, just declare it outside of the loop, then work with it after your loop processing is done:
string[] arr = ...
for (int z = 0; z < alParmValues.Count; z++)
{
// work with arr...
}
var item = arr[3]; // Accessed outside of loop.
However, there seem to be a few things wrong with your code. I'd recommend thinking a little bit more about the loop body and what you're trying to do there. Consider this line, for example:
for (int z = 0; z < alParmValues.Count; z++)
{
// ...
string[] asd = alParmValues[z].ToString().Split(',');
// There aren't any more references to asd after this point in the loop,
// so this assignment serves no purpose and only keeps its last assigned
// value.
}
This assignment is pointless; every time you go through the loop, you just overwrite the previous value of asd, and you never use it later in the loop.
The scope of both asd and def are limited to the body of the for loop. If you have to access them you need to declare them outside the loop. Is there a problem in putting them out?
Take a look at the Collection Classes Tutorial on MSDN.
Both 'asd' and 'def' are string arrays whose scope is limited to the for loop. You cannot access them outside the loop. If you want to do so, try declaring them outside the for loop.
First, if you want access to the data extracted/computed inside the loop, you must declare a container for the results outside the loop, and then populate its values inside the loop.
Second, don't think about casting the arrays returned from the split method, but rather think about processing their contents.
Assuming that you want the combined results from all elements of the original alParmValues array in a single pair of results, I'd use something like the following pseudo-code. Of course, you'll need to fill in the type for your alParmValues and alMethSign elements, add semicolons, etc. (Because your question didn't explain the content and relationships between the two arrays being processed in your loop, I've just treated them independently.) This isn't complete code, but just a sketch to get you started:
ArrayList allValues = new ArrayList()
foreach (??? parameter in alParmValues) {
foreach (String value in parameter.ToString().Split(',')) {
allValues.add(value)
}
}
ArrayList allMethSignValues = new ArrayList()
foreach (??? methSign in alMethSign) {
String thisString = methSign.toString()
int open = thisString.indexOf('(')
int close = thisString.indexOf(')')
String parenPart = thisString.substring(open + 1, close - open - 1)
foreach (String value in parenPart.split(',')) {
allMethSignValues.add(value)
}
}

Categories

Resources