How to return a jagged array - c#

I have a function which use a 2D jagged array to save records from an SQL query.
How do return the jagged array correctly?
I tried something like:
public string[][] GetResult()
{
return result;
}
And in my main programm:
string[][] test = new string[server1.GetResult().Length][];
test = server1.GetResult();
Well, as expected, it didn't work.
I don't know how to fix my problem.

Jagged arrays are simply arrays of arrays.
In your code:
string[][] test = new string[server1.GetResult().Length][];
test = Gronforum.GetResult();
You first assign a new array to test, then overwrite it with the return value from GetResult(). The code does the same as:
string[][] test = Gronforum.GetResult();
Now the GetResult() should return a string[][] - try this to get a feel of working with jagged arrays:
public string[][] GetResult()
{
string[][] result = new string[2][];
result[0] = new string[] { "1", "2" };
result[1] = new string[2];
result[1][0] = "a";
result[1][1] = "b";
return result;
}
You could supply a reference to the result of the SQL operation to that method so it has access to the data, to "convert" it to a string[][].

Related

Make an array completely empty

I want to make this array completely empty.
string[] strNumbers = new string[3] { "1", "2", "3" };
So I want it to be this
strNumbers = {}
Using the function
Array.Clear();
why don't use this
strNumbers = new string[3] ;
Array.Clear will set elements of array to the default values (null for string) but will keep the size of array. Just new up the array:
strNumbers = new string[0];
Or even better:
strNumbers = Array.Empty<string>();
Unclear what you are asking.
Create a new array with no elements
string[] strNumbers = new string[0];
or
string[] strNumbers = Array.Empty<string>();
strNumbers.Length will be zero
Create a new array but leave contents empty
string[] strNumbers = new string[3];
contents will be three null values
Take an existing array and remove all the elements
Arrays in C# are of fixed size. You cannot add or remove elements from arrays. If you need variable size arrays, use List<string> or some other collection type.
Take an existing array and set the contents to their default values
for(int i=0; i<strNumbers.Length; i++)
{
strNumbers[i] = default(string);
}
or
Array.Clear(strNumbers, 0, strNumbers.Length);

Can I use the C# 8 range operator with a list instead of an array? [duplicate]

With C# 8 we got ranges to get "sub lists".
While this works:
var array = new string[] { "abc", "def", "ghi" };
var subArray = array[0..1]; // works
This does not:
var list = new List<string> { "abc", "def", "ghi" };
var subList = list[0..1]; // does not work
How can I use ranges with lists?
List does not itself support Ranges. However, if all you have is a Range, you can create a helpful extension method like so:
public static class ListExtensions
{
public static List<T> GetRange<T>(this List<T> list, Range range)
{
var (start, length) = range.GetOffsetAndLength(list.Count);
return list.GetRange(start, length);
}
}
Then you can use it to get your sub-List:
var list = new List<string> { "abc", "def", "ghi" };
var subList = list.GetRange(0..1);
You can use ToArray() method to solve the problem:
var list = new List<string> { "abc", "def", "ghi" };
var subList = list.ToArray()[0..1]; // works
But note that List<T> has GetRange method that does the same thing:
var list = new List<string> { "abc", "def", "ghi" };
var subList = list.GetRange(0,1);//abc
Just for completeness, I know this isn't exactly what OP is asking for.
List<T> has a GetRange-Method.
https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.getrange?view=net-5.0
List<?> range = list.GetRange(0,5);
It doesn't have much to do with the new language feature but it does what it says.
Please do not use ToArray only to use that fancy new language feature. It's not worth the overhead.
Unfortunately you can't. From the language specification:
For example, the following .NET types support both indices and ranges: String, Span, and ReadOnlySpan. The List supports indices but doesn't support ranges.
Type Support for ranges and indices.
So the only way would be something like this, which is a bit clunky:
var subList = list.ToArray()[0..1];
Edit: I will leave the rest of my answer here for the record, but I think the answer using Range is more elegant, and will be significantly faster, especially for large slices.
Benchmarking and Extension Method
The following demonstrates how much slower using ToArray() can be (using LINQPad - F.Rnd.Str is my own helper method for generating random strings):
var list = new List<string>();
for (int i = 0; i < 100000; i++)
{
list.Add(F.Rnd.Str);
}
// Using ToArray()
var timer = new Stopwatch();
timer.Start();
var subList0 = list.ToArray()[42..142];
timer.Stop();
timer.ElapsedTicks.Dump("ToArray()");
// Using Indices
timer.Reset();
timer.Start();
var subList1 = new List<string>();
for (int i = 42; i < 142; i++)
{
subList1.Add(list[i]);
}
timer.Stop();
timer.ElapsedTicks.Dump("Index");
// ToArray()
// 3136
// Index
// 28
Therefore an extension method like this will be very quick:
public static class ListExtensions
{
public static List<T> GetSlice<T>(this List<T> #this, int first, int last)
{
var slice = new List<T>();
for (int i = first; i < last; i++)
{
slice.Add(#this[i]);
}
return slice;
}
}
Then you can add this to the benchmark:
// Using Extension Method
timer.Reset();
timer.Start();
var subList2 = list.GetSlice(42, 142);
timer.Stop();
timer.ElapsedTicks.Dump("Extension");
Benchmark results:
// ToArray()
// 2021
// Index
// 16
// Extension
// 15
Range
One of the answers uses Range to achieve the same thing, so for comparison:
timer.Reset();
timer.Start();
var range = new Range(42, 142);
var (start, length) = range.GetOffsetAndLength(list.Count);
var subList3 = list.GetRange(start, length);
timer.Stop();
timer.ElapsedTicks.Dump("Range");
Benchmark results:
// ToArray()
// 2056
// Index
// 21
// Extension
// 16
// Range
// 17
You can see the bottom three methods are essentially the same in terms of speed (as I run it multiple times they all vary between 15-21 ticks).
Rather than converting the List<T> by copying it to array you could access the internals as a Span<T>.
This saves unnecessary allocation and copying.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
public class Program
{
public static void Main()
{
var list = new List<string> { "abc", "def", "ghi" };
ReadOnlySpan<string> subList = CollectionsMarshal.AsSpan(list)[0..1];
Console.WriteLine(subList.Length);
Console.WriteLine(subList[0]);
}
}

check a string array from a list contains a string from another list or vice versa

Is there a easy way to do this using linq?
I want to check and return true or false, whether any string from list1 contains a string from array1. In the below example that would be string2value and i would want to return true.
Also similarly i want to check whether any array1 would contain a string from list1. That would be string1blah and so that would return true as well. Thanks!
List<string> list1 = new List<string>{"string1","string2value"};
string[] array1 = new string[2] {"string1blah","string2"};
I have a couple of versions, but it does not work all the time.
array1.ToList().Any(a=>list1.Contains(a))
list1.Any(l=>array1.ToList().Contains(l))
You can try this:
var result= list1.Where(s=>array1.Any(s1=>s.Contains(s1)));
Per each string in the list1, you see if there is an element in array1 that is contained in s string.
The way your question is worded it is hard to understand what you want.
If you want all the strings in one list which are substrings of an element in the other list, then this should work:
var substrings = myList.Where(bigstring => myArray.Any(substring => bigstring.Contains(substring)));
If you just want to know whether such an element exists, then do this:
bool myCondition = myList.Any(bigstring => myArray.Any(substring => bigstring.Contains(substring)));
If you're wanting pretty linq, you can do:
static void Main(string[] args)
{
var list1 = new List<string> { "string1", "string2value" };
var array1 = new string[] { "string1blah", "string2" };
var result = from sl in list1
from sa in array1
where sl.Contains(sa) || sa.Contains(sl)
select new { sl, sa };
foreach (var x in result)
{
Console.WriteLine(x);
}
}
Which gives nice output
{ sl = string1, sa = string1blah }
{ sl = string2value, sa = string2 }
You can also use linq query expressions if you want.
Give this code:
List<string> list1 = new List<string> { "string1", "string2value" };
string[] array1 = new string[2] { "string1blah", "string2" };
I want to check and return true or false, whether any string from list1 contains a string from array1. In the below example that would be string2value and i would want to return true.
You can do it like this:
var result = from l1 in list1
from a1 in array1
where l1.Contains(a1)
select l1; // Or select true if you want to just return true
Also similarly i want to check whether any array1 would contain a string from list1. That would be string1blah and so that would return true as well. Thanks!
You can modify the above to achieve it like this:
var result = from l1 in list1
from a1 in array1
where a1.Contains(l1)
select a1;
To return true or false (as you've mentioned in the OP Comments), you would modify the call to count the items contained, and if greater than 0, return true.
EDIT Thanks Dax Fohl
var list1 = new List<string> {"Test1", "Test2", "Test3", "Test4"};
var array1 = new string[] {"Test3", "Test4", "Test5", "Test6"};
var result = list1.Any(s => array1.Any(s.Contains));

What's the difference of the ways of array initialization? [duplicate]

What are all the array initialization syntaxes that are possible with C#?
These are the current declaration and initialization methods for a simple array.
string[] array = new string[2]; // creates array of length 2, default values
string[] array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
string[] array = new[] { "A", "B" }; // created populated array of length 2
Note that other techniques of obtaining arrays exist, such as the Linq ToArray() extensions on IEnumerable<T>.
Also note that in the declarations above, the first two could replace the string[] on the left with var (C# 3+), as the information on the right is enough to infer the proper type. The third line must be written as displayed, as array initialization syntax alone is not enough to satisfy the compiler's demands. The fourth could also use inference. So if you're into the whole brevity thing, the above could be written as
var array = new string[2]; // creates array of length 2, default values
var array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
var array = new[] { "A", "B" }; // created populated array of length 2
The array creation syntaxes in C# that are expressions are:
new int[3]
new int[3] { 10, 20, 30 }
new int[] { 10, 20, 30 }
new[] { 10, 20, 30 }
In the first one, the size may be any non-negative integral value and the array elements are initialized to the default values.
In the second one, the size must be a constant and the number of elements given must match. There must be an implicit conversion from the given elements to the given array element type.
In the third one, the elements must be implicitly convertible to the element type, and the size is determined from the number of elements given.
In the fourth one the type of the array element is inferred by computing the best type, if there is one, of all the given elements that have types. All the elements must be implicitly convertible to that type. The size is determined from the number of elements given. This syntax was introduced in C# 3.0.
There is also a syntax which may only be used in a declaration:
int[] x = { 10, 20, 30 };
The elements must be implicitly convertible to the element type. The size is determined from the number of elements given.
there isn't an all-in-one guide
I refer you to C# 4.0 specification, section 7.6.10.4 "Array Creation Expressions".
Non-empty arrays
var data0 = new int[3]
var data1 = new int[3] { 1, 2, 3 }
var data2 = new int[] { 1, 2, 3 }
var data3 = new[] { 1, 2, 3 }
var data4 = { 1, 2, 3 } is not compilable. Use int[] data5 = { 1, 2, 3 } instead.
Empty arrays
var data6 = new int[0]
var data7 = new int[] { }
var data8 = new [] { } and int[] data9 = new [] { } are not compilable.
var data10 = { } is not compilable. Use int[] data11 = { } instead.
As an argument of a method
Only expressions that can be assigned with the var keyword can be passed as arguments.
Foo(new int[2])
Foo(new int[2] { 1, 2 })
Foo(new int[] { 1, 2 })
Foo(new[] { 1, 2 })
Foo({ 1, 2 }) is not compilable
Foo(new int[0])
Foo(new int[] { })
Foo({}) is not compilable
Enumerable.Repeat(String.Empty, count).ToArray()
Will create array of empty strings repeated 'count' times. In case you want to initialize array with same yet special default element value. Careful with reference types, all elements will refer same object.
In case you want to initialize a fixed array of pre-initialized equal (non-null or other than default) elements, use this:
var array = Enumerable.Repeat(string.Empty, 37).ToArray();
Also please take part in this discussion.
var contacts = new[]
{
new
{
Name = " Eugene Zabokritski",
PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }
},
new
{
Name = " Hanying Feng",
PhoneNumbers = new[] { "650-555-0199" }
}
};
Example to create an array of a custom class
Below is the class definition.
public class DummyUser
{
public string email { get; set; }
public string language { get; set; }
}
This is how you can initialize the array:
private DummyUser[] arrDummyUser = new DummyUser[]
{
new DummyUser{
email = "abc.xyz#email.com",
language = "English"
},
new DummyUser{
email = "def#email.com",
language = "Spanish"
}
};
Just a note
The following arrays:
string[] array = new string[2];
string[] array2 = new string[] { "A", "B" };
string[] array3 = { "A" , "B" };
string[] array4 = new[] { "A", "B" };
Will be compiled to:
string[] array = new string[2];
string[] array2 = new string[] { "A", "B" };
string[] array3 = new string[] { "A", "B" };
string[] array4 = new string[] { "A", "B" };
Repeat without LINQ:
float[] floats = System.Array.ConvertAll(new float[16], v => 1.0f);
int[] array = new int[4];
array[0] = 10;
array[1] = 20;
array[2] = 30;
or
string[] week = new string[] {"Sunday","Monday","Tuesday"};
or
string[] array = { "Sunday" , "Monday" };
and in multi dimensional array
Dim i, j As Integer
Dim strArr(1, 2) As String
strArr(0, 0) = "First (0,0)"
strArr(0, 1) = "Second (0,1)"
strArr(1, 0) = "Third (1,0)"
strArr(1, 1) = "Fourth (1,1)"
For Class initialization:
var page1 = new Class1();
var page2 = new Class2();
var pages = new UIViewController[] { page1, page2 };
Another way of creating and initializing an array of objects. This is similar to the example which #Amol has posted above, except this one uses constructors. A dash of polymorphism sprinkled in, I couldn't resist.
IUser[] userArray = new IUser[]
{
new DummyUser("abc#cde.edu", "Gibberish"),
new SmartyUser("pga#lna.it", "Italian", "Engineer")
};
Classes for context:
interface IUser
{
string EMail { get; } // immutable, so get only an no set
string Language { get; }
}
public class DummyUser : IUser
{
public DummyUser(string email, string language)
{
m_email = email;
m_language = language;
}
private string m_email;
public string EMail
{
get { return m_email; }
}
private string m_language;
public string Language
{
get { return m_language; }
}
}
public class SmartyUser : IUser
{
public SmartyUser(string email, string language, string occupation)
{
m_email = email;
m_language = language;
m_occupation = occupation;
}
private string m_email;
public string EMail
{
get { return m_email; }
}
private string m_language;
public string Language
{
get { return m_language; }
}
private string m_occupation;
}
For the class below:
public class Page
{
private string data;
public Page()
{
}
public Page(string data)
{
this.Data = data;
}
public string Data
{
get
{
return this.data;
}
set
{
this.data = value;
}
}
}
you can initialize the array of above object as below.
Pages = new Page[] { new Page("a string") };
Hope this helps.
hi just to add another way:
from this page :
https://learn.microsoft.com/it-it/dotnet/api/system.linq.enumerable.range?view=netcore-3.1
you can use this form If you want to Generates a sequence of integral numbers within a specified range strat 0 to 9:
using System.Linq
.....
public int[] arrayName = Enumerable.Range(0, 9).ToArray();
You can also create dynamic arrays i.e. you can first ask the size of the array from the user before creating it.
Console.Write("Enter size of array");
int n = Convert.ToInt16(Console.ReadLine());
int[] dynamicSizedArray= new int[n]; // Here we have created an array of size n
Console.WriteLine("Input Elements");
for(int i=0;i<n;i++)
{
dynamicSizedArray[i] = Convert.ToInt32(Console.ReadLine());
}
Console.WriteLine("Elements of array are :");
foreach (int i in dynamicSizedArray)
{
Console.WriteLine(i);
}
Console.ReadKey();
Trivial solution with expressions. Note that with NewArrayInit you can create just one-dimensional array.
NewArrayExpression expr = Expression.NewArrayInit(typeof(int), new[] { Expression.Constant(2), Expression.Constant(3) });
int[] array = Expression.Lambda<Func<int[]>>(expr).Compile()(); // compile and call callback
To initialize an empty array, it should be Array.Empty<T>() in dotnet 5.0
For string
var items = Array.Empty<string>();
For number
var items = Array.Empty<int>();
Another way is by calling a static function (for a static object) or any function for instance objects. This can be used for member initialisation.
Now I've not tested all of this so I'll put what I've tested (static member and static function)
Class x {
private static Option[] options = GetOptionList();
private static Option[] GetOptionList() {
return (someSourceOfData).Select(dataitem => new Option()
{field=dataitem.value,field2=dataitem.othervalue});
}
}
What I'd love to know is if there is a way to bypass the function declaration. I know in this example it could be used directly, but assume the function is a little more complex and can't be reduced to a single expression.
I imagine something like the following (but it doesn't work)
Class x {
private static Option[] options = () => {
Lots of prep stuff here that means we can not just use the next line
return (someSourceOfData).Select(dataitem => new Option()
{field=dataitem.value,field2=dataitem.othervalue});
}
}
Basically a way of just declaring the function for the scope of filling the variable.
I'd love it if someone can show me how to do that.
For multi-dimensional array in C# declaration & assign values.
public class Program
{
static void Main()
{
char[][] charArr = new char[][] { new char[] { 'a', 'b' }, new char[] { 'c', 'd' } };
int[][] intArr = new int[][] { new int[] { 1, 2 }, new int[] { 3, 4 } };
}
}

passing normal items and array items to params function C#

i want to add new row to table but by passing both normal variables and array variable like the example below
int value1=1;
int value2=2;
int[] numbers = new int[] {3, 4, 5};
DataTable1.Rows.Add(value1,value2,numbers) // numbers as single items so the row will contain 5 values (1,2,3,4,5)
so should i build a new array and pass it ? or there a code spell to do that ?
thanks
This helper method will create a list from 1 to 5:
public IEnumerable<T> GetItemsAndCollectionsAsItems<T>(params object[] itemsAndCollections)
{
var result = new List<T>();
foreach (var itemOrCollection in itemsAndCollections)
{
var collection = itemOrCollection as IEnumerable<T>;
if (collection == null)
{
result.Add((T)itemOrCollection);
}
else
{
result.AddRange(collection);
}
}
return result;
}
And you call it this way:
int value1 = 1;
int value2 = 2;
int[] numbers = new int[] { 3, 4, 5 };
// Returns 1,2,3,4,5
IEnumerable<int> values = GetItemsAndCollectionsAsItems<int>(value1, value2, numbers);
Not sure to be happen with this Int Array but yah, have a look on this link, which stores data same as you want. Simply some tricky things have to do.

Categories

Resources