Get input array of particular type - c#

I need to get array input in particular types - example for int below.
string[] input = Console.ReadLine().Split(' ');
int[] array = new array[input.Length];
for(int i = 0; i < input.Length; i++)
{
array[i] = int.Parse(input[i]);
}
This is working, but in case of multiple such arrays of different type it takes up too much code to get input in string array and then parse it into required type for every input array.
Is there any shortcut way to get this done ?
It is guaranteed that complete array input will lie on single line.

Have a look at Enumerable.Select:
int[] array = input.Select(int.Parse).ToArray();
You could easily change this to another type, for example:
class StringContainer
{
public string Value { get; set; }
}
StringContainer[] array = input.Select(x => new StringContainer { Value = x }).ToArray();
You could even define an extension method:
public static TOut[] Convert<TIn, TOut>(this TIn[] input, Func<TIn, TOut> selector)
{
return input.Select(selector).ToArray();
}
Then use like this:
int[] intArray = input.Convert(int.Parse);
StringContainer[] scArray = input.Convert(x => new StringContainer { Value = x });
The type of the output array is inferred from the return type of the delegate.

Related

How to store multiple datatype values into single list without defining class?

Expected result :
List<something> obj = new List<something>(); //something is i need.
string[] val = new string[] {"hi","20"}; //here I used static but input data fetch from CSV file. So we don't know when which type of data will come?.
int intval;
for(int i=0;i<val.Length;i++)
{
if(int.TryParse(val[i],out intval)
{
obj.add(intval); //here I face the error "Cannot implicitly convert int to string"
}
else
{
obj.add(val[i]);
}
}
I need to add int value and also string value into the same list. But The condition is Developer don't know when which type of value will come. So here I used TryParse to convert values and store into list.
How to declare a list or any other methods are there?
Note: Don't use Class to declare field and define like List<classname> val = new List<classname>();
Not sure why you want to do this but I think the code below is what you're looking for. I suppose you can later check if each list value typeof is string/int but why store multi value types in one list like this?
string[] val = new string[] { "hi", "20" };
List<object> objs = val.Select(x =>
{
if (int.TryParse(x, out var intval))
return (object)intval;
else
return (object)x;
}).ToList();
If you just need to store all the results that you get to a single list without caring about the type then dont Parse to int type like
for (int i = 0; i < val.Length; i++)
{
//simply add the
obj.add(val[i]);
}
Just use a List<object>. Every type ultimately derives from object:
List<object> obj = new List<object>();
string[] val = new string[] {"hi","20"};
for(int i = 0; i < val.Length; i++)
{
if(int.TryParse(val[i], out var intval)
{
obj.add(intval);
}
else
{
obj.add(val[i]);
}
}

How to call function with List in head

I want to send along several integers with my function through a list like this:
public string createCompleteJump(List<int>kID)
kID is they key ID which is connected to several dictionaries hence why it is important to select different integers.
function:
public string createCompleteJump(List<int>kID)
{
// List<int> kID = new List<int>(); // Key ID
double vID = 3; // Value ID
string v2ID = "Framåt";
var myKey = qtyScrews[kID[0]].FirstOrDefault(y => y == vID);
var myKey2 = qtyFlips[kID[1]];
var myKey3 = jumpCombination[kID[2]].FirstOrDefault(y => y == v2ID);
var myKey4 = jumpHeight[kID[3]];
var myKey5 = startPos[kID[4]];
var str = $"{myKey}{myKey2}{myKey3}{myKey4}{myKey5}";
Console.Write("\nCompleteJump:" + str);
return str;
}
How would I send along 5 arguments when calling the function through a list?
Eg:
public string createCompleteJump(3,4,2,3,4)
You either need to create a list to pass as argument:
createCompleteJump(new List<int> {3,4,2,3,4});
or you could change your method to accept an undefined number of arguments:
public string createCompleteJump(params int[] kID)
{ /* ... */ }
The params key word states that there can be an arbitrary number of int and that they are combined into an array:
createCompleteJump(3,4,2,3,4);
results in an int[] array containing the specified values.
use params keyword:
public string createCompleteJump(params int[] kID)
https://msdn.microsoft.com/library/w5zay9db.aspx
You can use params or you can instantiate your list to be sent to your function, like this:
List<int> keyIDList = new List<int> {3,4,2,3,4};
createCompleteJump(keyIDList)

How to convert string array to int array to make calculation?

I want to read the integers after the /. thats why i tried to use this code:
while ((line = file.ReadLine()) != null)
{
string[] ip = line.Split('/');
Console.WriteLine(ip[1]);
}
this code returns me this integers as string. I want to some math calculation with this numbers ,for example, multiplication. I tried this code but it doesnt work
int[] intArray = Array.ConvertAll(ip, int.Parse);
You are trying to convert each item of ip array to integer. At lease second item of it - "24 25 26 27" cannot be converted to single integer value. You should take this item of ip array, split it by white space and then parse each part to integer:
int[] intArray = ip[1].Split().Select(Int32.Parse).ToArray();
Or
int[] intArray = Array.ConvertAll(ip[1].Split(), Int32.Parse);
If its really about IP-Adresses, this might help
class IPV4Adress
{
public int BlockA {get; set;}
public int BlockB {get; set;}
public int BlockC {get; set;}
public int BlockD {get; set;}
public IPV4Adress(string input)
{
If(String.IsNullOrEmpty(input))
throw new ArgumentException(input);
int[] parts = input.Split(new char{',', '.'}).Select(Int32.Pase).ToArray();
BlockA = parts[0];
BlockB = parts[1];
BlockC = parts[2];
BlockD = parts[3];
}
public override ToString()
{
return String.Format("{0}.{1}.{2}.{3}",BlockA, BlockB, BlockC, BlockD);
}
}
Then read it from File:
IPV4Adress[] adresses = File.ReadLines(fileName).SelectMany(line=>line.Split('/')).Select(part => new IPV4Adress(part)).ToArray();
Given an array you can use the Array.ConvertAll method:
int[] myInts = Array.ConvertAll(arr, s => int.Parse(s));
(or)
int[] myInts = arr.Select(s => int.Parse(s)).ToArray();
(Or)
var converted = arr.Select(int.Parse)
A LINQ solution is similar, except you would need the extra ToArray call to get an array:
int[] myInts = arr.Select(int.Parse).ToArray();
Sourec

Adding data to a generic string Array C#

I'm learning about generics in C#, and I'm trying to make a generic array and add some strings to it. I can easily add int values to it, but I can't figure out how to make it work with strings. When I'm trying to use strings I get NullReferenceException.
I have a class called myArray, and it looks like this:
class MyArray<T> : IComparable<T>, IEnumerable<T>, IEnumerator<T>
{
T[] data = new T[10];
int current = -1;
public T[] Data
{
get { return data; }
}
public void Add(T value)
{
for (int i = 0; i < data.Length; i++)
{
if (data[i].Equals(default(T)))
{
data[i] = value;
return;
}
}
T[] tmp = new T[data.Length + 10];
data.CopyTo(tmp, 0);
Add(value);
}
In my mainform I add the data like this:
class Program
{
static void Main(string[] args)
{
MyArray<string> StringArray = new MyArray<string>();
StringArray.Add("ONE");
StringArray.Add("TWO");
}
}
The default of string is null as it is a reference type, not a value type. You are constructing a new array of type T[], which results in an array filled with the default value of T, which in this case is null.
Following that, data[i].Equals(default(T)) throws NRE as you are trying to call null.Equals(...).
Your array is being initialized with null values, so you're getting a NRE at this line:
if (data[i].Equals(default(T)))
if (data[i].Equals(default(T))) is where the issue lies. In a new string (or any other reference type) array,
var array = new String[10];
each element in the array is null by default. So when you say
data[i].Equals(default(T)
and data[i] is null, you're calling a method on a null reference, thus causing the exception to be thrown.
This doesn't happen for value types, as the array is initialized to the default value of whatever the value type is.
This is part of the problem with generics--you can't always treat reference types and value types the same.
Try this instead, to avoid default:
private int _currentIndex = 0;
public void Add(T value)
{
data[_currentIndex] = value;
_currentIndex++;
if(_currentIndex == data.Length)
{
T[] tmp = new T[data.Length + 10];
data.CopyTo(tmp, 0);
data = tmp;
_currentIndex = 0;
}
}

Comparing two enum *types* for equivalence?

In my application, I have two equivalent enums. One lives in the DAL, the other in the service contract layer. They have the same name (but are in different namespaces), and should have the same members and values.
I'd like to write a unit test that enforces this. So far, I've got the following:
public static class EnumAssert
{
public static void AreEquivalent(Type x, Type y)
{
// Enum.GetNames and Enum.GetValues return arrays sorted by value.
string[] xNames = Enum.GetNames(x);
string[] yNames = Enum.GetNames(y);
Assert.AreEqual(xNames.Length, yNames.Length);
for (int i = 0; i < xNames.Length; i++)
{
Assert.AreEqual(xNames[i], yNames[i]);
}
// TODO: How to validate that the values match?
}
}
This works fine for comparing the names, but how do I check that the values match as well?
(I'm using NUnit 2.4.6, but I figure this applies to any unit test framework)
Enum.GetValues:
var xValues = Enum.GetValues(x);
var yValues = Enum.GetValues(y);
for (int i = 0; i < xValues.Length; i++)
{
Assert.AreEqual((int)xValues.GetValue(i), (int)yValues.GetValue(i));
}
I would flip the way you check around. It is easier to get a name from a value instead of a value from a name. Iterate over the values and check the names at the same time.
public static class EnumAssert
{
public static void AreEquivalent(Type x, Type y)
{
// Enum.GetNames and Enum.GetValues return arrays sorted by value.
var xValues = Enum.GetValues(x);
var yValues = Enum.GetValues(y);
Assert.AreEqual(xValues.Length, yValues.Length);
for (int i = 0; i < xValues.Length; i++)
{
var xValue = xValues.GetValue( i );
var yValue = yValues.GetValue( i );
Assert.AreEqual(xValue, yValue);
Assert.AreEqual( Enum.GetName( x, xValue ), Enum.GetName( y, yValue ) );
}
}
}

Categories