C# converted from VB doesn't work - c#

I used code converter to go from VB to C# and I get errors in c#. specifically, error on Item and on string.join(",", Flop.ToArray). Error says it doesn't contain a definition for item but it works in VB.
VB
Dim Flop As New List(Of String)
For x As Integer = 0 To Dataset9.Tables(0).Rows.Count - 1 'ROWS
Flop.Add(Dataset9.Tables(0).Rows(x).Item("Id"))
Next
strAllRoleNames = String.Join(",", Flop.ToArray)
C#
List<string> Flop = new List<string>();
for (int x = 0; x <= Dataset9.Tables[0].Rows.Count - 1; x++)
{
Flop.Add(Dataset9.Tables[0].Rows[x].Item["Id"]);
}
strAllRoleNames = string.Join(",", Flop.ToArray);

Try this:
List<string> Flop = new List<string>();
for (int x = 0; x <= Dataset9.Tables[0].Rows.Count - 1; x++)
{
Flop.Add(Dataset9.Tables[0].Rows[x]["Id"].ToString());
}
strAllRoleNames = string.Join(",", Flop.ToArray());
They three keys that were missing here
Accessing the item in a row, you need to use the C# default indexer as Item doesn't exist in C#
Since the cell in a row is an object and you want a string, need to explicitly call ToString
When calling ToArray, you need the () at the end in C#

try...
Flop.Add(Dataset9.Tables[0].Rows[x]["Id"].ToString());

ToArray is a method()
List<string> Flop = new List<string>();
for (int x = 0; x <= Dataset9.Tables[0].Rows.Count - 1; x++)
{
Flop.Add(Dataset9.Tables[0].Rows[x]["Id"]);
}
strAllRoleNames = string.Join(",", Flop.ToArray());

In a more concise way you can try below instead:
strAllRoleNames = string.Join(",", Dataset9.Tables[0].AsEnumerable()
.Select(C => Convert.ToString(C["Id"]))
.ToArray());

Try the below changes:
Dataset9.Tables[0].Rows[x].Item["Id"] => Dataset9.Tables[0].Rows[x]["Id"]
Flop.ToArray => Flop.ToArray()

Related

Why not all the items in the List that not contains the string not removed from the List?

var g = urls;
if (g.Count > 1)
{
for(int i = g.Count - 1; i > 0; i--)
{
if (!g[i].Contains("Test"))
{
g.RemoveAt(i);
}
}
}
I create a copy of the List then checking for specific string in each item but there are 23 items left in g one of them is not containing the word "Test" but was not removed it's the first item in the list at index 0.
Because your for loop is not touching element present at index 0, to fix this issue update your for loop to
for(int i = g.Count - 1; i >= 0; i--)
{ //^^^^ This is missing in your code
if (!g[i].Contains("Test"))
{
g.RemoveAt(i);
}
}
To make it more readable, you can traverse from start instead of reverse traversal and store expected element of g into a new list.
var result = new List<string>();
for(int i = 0; i < g.Count; i++)
{
if (g[i].Contains("Test"))
{
result.Add(g[i]);
}
}
To make it more elegant you can use Linq Where() clause,
var result = g.Where(x => x.Contains("Test")).ToList();
If you are looking for a solution which actually update input list (in Your case it is g), then you can use solution suggested by #canton7,
g.RemoveAll(item => !item.Contains("Test"))
Console.WriteLine(string.Join(" ", g));
.RemoveAll()
.NET Fiddle
var g = urls.Where(u => u.Contains("Test")).ToList();

Why the variable defined in the for loop is going above the upper limit when I want to print the output?

string table = "?-?";
string[] chars = { "&", "x" };
IEnumerable<string> vs = new List<string> { "" };
for (int i = 0; i < table.Length; i++)
{
if (table[i] != '?')
vs = vs.Select(x => x + table[i]);
else
vs = vs.SelectMany(x => chars.Select(y => x + y));
}
I can run and compile the above without any exceptions, but when I try to see the elements in vs, with Console.WriteLine(string.Join(", ", vs));, I get a System.IndexOutOfRangeException in the line vs = vs.Select(x => x + table[i]);.
The cause of the exception is i.
The strange thing is that i is 3, in the "Locals" window, but I have i < table.Length in the for loop. So i cannot be 3 but it is!
My question is why i becomes 3 and why the exception only appears when I want to print the output.
I've tried the following to print the output too, but I got the same result.
foreach (var comb in vs)
Console.WriteLine(comb);
Look into the "Locals" window: your i variable gets the value of 3 - thus the exception.
And why is it 3? This is because you incremented it in the loop. But wait, your Select is inside of the loop, so it shouldn't be greater than 2, right?
Wrong.
This is called "a variable captured by a lambda". Search for this to read more.
The solution:
for (int i = 0; i < table.Length; i++)
{
int j = i;
vs = vs.Select(x => x + table[j]);
// and so on
}
Well, you need to call ToList() on the Linq query. Make changes like
public static void Main()
{
string table = "?-?";
string[] chars = { "&", "x" };
List<string> vs = new List<string> { "" };
for (int i = 0; i < table.Length; i++)
{
if (table[i] != '?')
vs = vs.Select(x => x + table[i]).ToList();
else
vs = vs.SelectMany(x => chars.Select(y => x + y)).ToList();
}
Console.WriteLine(string.Join(", ", vs));
}
Output:
&-&, &-x, x-&, x-x

Fastest way to split a large list of integers into List of strings in C#

My goal is to split a list of 24043 integers into strings like:
"?ids=" + "1,2,3...198,199,200"
Can you think of a better solution than mine in terms of performance?
public List<string> ZwrocListeZapytan(List<int> listaId)
{
var listaZapytan = new List<string>();
if (listaId.Count == 0) return listaZapytan;
var zapytanie = "?ids=";
var licznik = 1;
for (var i = 0; i < listaId.Count; i++)
{
if (licznik == 200 || i == listaId.Count - 1)
{
listaZapytan.Add(zapytanie + listaId[i]);
zapytanie = "?ids=";
licznik = 1;
}
else
{
zapytanie += listaId[i] + ",";
licznik++;
}
}
return listaZapytan;
}
Using Linq:
Assuming listaId is the list of integers that has to be converted:
var result = listaId.GroupBy(x => x / 200)
.Select(y => "?ids=" + string.Join(",", y)).ToList();
.GroupBy() helps take 200 at a time
.Select() is used to combine them together in the format like the OP suggested i.e ?ids=1,2,... using string.Join()
Can you think of a better solution than mine in terms of performance?
It terms of performance the only thing that comes to my mind as an enhancement for your code is to use a StringBuilder when you concatenate the string:
public List<string> ZwrocListeZapytan(List<int> listaId)
{
var listaZapytan = new List<string>();
if (listaId.Count == 0) return listaZapytan;
StringBuilder sb = new StringBuilder();
sb.Append("?ids=");
var licznik = 1;
for (var i = 0; i < listaId.Count; i++)
{
if (licznik == 200 || i == listaId.Count - 1)
{
listaZapytan.Add(sb.ToString() +listaId[i]);
sb.Clear();
sb.Append("?ids=");
licznik = 1;
}
else
{
sb.Append(listaId[i] + ",");
licznik++;
} return listaZapytan;
}
Otherwise you could make the for-loop run in steps of the 200. At each step take the numbers from the given range and use String.Join to create the string:
// TEST DATA
List<int> listaId = Enumerable.Range(1, 420).ToList();
List<string> listaZapytan = new List<string>();
int stepsize = 200;
for (int i = 0; i < listaId.Count; i +=stepsize)
{
listaZapytan.Add("?ids=" + String.Join(",", listaId.Skip(i).Take(stepsize)));
}
Could you please make a try with this and let me know whether this approach helps to solve your issue?
List<int> listaId = Enumerable.Range(0, 24043).ToList();
var items = String.Join("", Enumerable.Range(0, 24043)
.Select((x,i)=>i%200==0?
"\n?ids=" + x.ToString():
"," + x.ToString()));
Running Example
Here we are using Enumerable.Range to generate 24043 continuous numbers starting from 0. Then we can use the Select method to split them into a list of 200 and form the required string. If you want to get the output as a List, Remove the String.Join and add .ToList() at the end of the query. Current query produces output with 0-199 in the first list if you want 200 in that list means change the condition to i%201.

Put multiple values in an array

I have a issue that i cant solve.
Here is the code
sik input = new sik();
for (int i = 0; i < 5; i ++)
{
input.skId = securitiesArray[i].skId;
input.country = securitiesArray[i].country;
}
sik[] inputs = new sik[]
{
input
};
Now i know this will only put 1 value in the sik[] list.
How can i put all the 5 values in this list.
Thanks
Note: i cannot initialize ski[] first. This has to be done in that order.
Any reason that it has to be an array?
List<sik> input = new List<sik>();
for (int i = 0; i < 5; i ++)
{
var newInput = new sik();
newInput.skId = securitiesArray[i].skId;
newInput.country = securitiesArray[i].country;
input.Add(newInput);
}
The reason that the List is useful is that it can dynamically grow with you, so you have no need to worry about how many instances you may need to add.
MSDN Documentation for List and all of it's glorious methods
http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx
sik[] inputs = new sik[5];
for (int i = 0; i < 5; i ++)
{
sik input = new sik();
input.skId = securitiesArray[i].skId;
input.country = securitiesArray[i].country;
inputs[i] = input;
}
You can use Linq to do this.
sik[] inputs = securitiesArray.Select(item =>
new sik()
{
skId = item.skId,
country = item.country
}).ToArray();
You can't have variable size array, instead you can use List.
List<sik> siks = new List<sik>();
sik input = new sik();
for (int i = 0; i < 5; i ++)
{
input.skId = securitiesArray[i].skId;
input.country = securitiesArray[i].country;
siks.Add(input);
}
If you want array yet, use sik[] inputs = skis.ToArray();
You can also do this,
List<sik> input=new List<sik>();
for(int i=0;i<securitiesArray.Length;i++)
{
input.Add(new{skId=securitiesArray[i].skid,country=securitiesArray[i].country});
}
For what it's worth, here the Linq approach:
sik[] inputs = Enumerable.Range(0, 5)
.Select(i => new sik{ kId = securitiesArray[i].skId, country = securitiesArray[i].country})
.ToArray();
If securitiesArray is of type sik(the properties suggest), you can select directly from it:
sik[] inputs = securitiesArray.Take(5).ToArray();

Why does this simple code not work (ArgumentOutOfRangeException)

int i = 0;
int x = 10;
List<int> group = new List<int>();
while (i < x)
{
RichTextBoxShowTafel.AppendText(Convert.ToString(group[i]));
i++;
}
Why does this not work? I want to display the first 10 numbers of the List called: "group".
edit:
I actually want to create variables and print it in a row...
You never put anything in the group variable. You only instantiated an empty list.
And you'd be better off doing this:
foreach (int item in group)
{
RichTextBoxShowTafel.AppendText(item.ToString());
}
Because group is empty? As it has no elements, you can't access group[0], which is what you do in the first iteration
This is because group is empty!
When your loop first executes then i = 0 then you try Convert.ToString(groups[i]) which will always fail as there is no index of 0 in group
You should add elements in the list before you try to get them. The is the reason you got ArgumentOutOfRangeException. You can avoid the exception by adding element first.
int i = 0;
int x = 10;
List<int> group = new List<int>();
while (i < x)
{
group.Add(i);
RichTextBoxShowTafel.AppendText(Convert.ToString(group[i]));
i++;
}
If you are expecting group to be populated with numbers, you will have to do that yourself. Declaring and initializing it List<int> group = new List<int>(); only creates it. There is nothing inside. If you want to try putting variables in you can do something like this:
for(int j = 0; j < 10; j++)
{
group.Add(j);
}

Categories

Resources