How to write C# code that lists out object array value int 1-100 and output string text "EVEN" when it detect that object converted to int is divisible by 2?
class Program
{
static void Main(string[] args)
{
object[] numbers = new object[100];
numbers = Enumerable.Range(1, 100).Cast<object>().ToArray();
foreach (object number in numbers)
{
if(Convert.ToInt32(number) % 2 == 0)
{
number.ToString().Equals("Even");
}
Console.WriteLine(number);
}
Console.Read();
}
}
The problem you have is here:
number.ToString().Equals("Even");
This is getting the string representation of number and then comparing it for equality against the string Even, and doing nothing with the result. If you take a step back and think about this, it doesn't make any sense, because you want to print Even if number is even.
With your current program, you can do that like this:
if (Convert.ToInt32(number) % 2 == 0)
{
Console.WriteLine("{0} is even", number);
}
That said, there are a few things with your program that could be improved, as it doesn't seem as though you've got the hang of C#'s type system just yet.
Firstly, you are declaring an array of 100 objects like so:
object[] numbers = new object[100];
You already know you want to work with integers, so, instead of using object, you should use int:
int[] numbers = new int[100];
Next, you're generating a sequence of integers from 1-100:
numbers = Enumerable.Range(1, 100).Cast<object>().ToArray();
Enumerable.Range() returns a collection of integers, and .ToArray() converts that to an array of integers. As we're now using an array of integers, there is no need to cast them to object, so this can be simplified to:
numbers = Enumerable.Range(1, 100).ToArray();
There is one further simplification that can be made to this. Enumerable.Range() returns an IEnumerable<int>, which represents a collection of integers. This means that instead of declaring an array of 100 integers, generating a collection of integers, converting those to an array, and assigning them to numbers, we can do this instead:
IEnumerable<int> numbers = Enumerable.Range(1, 100);
There is another change that can be made here, but I'll describe at the end of this answer so let's look at the loop:
foreach (object number in numbers)
{
if (Convert.ToInt32(number) % 2 == 0)
{
Console.WriteLine(number);
}
}
As we've changed the code to use IEnumerable<int> instead of object[], we can now change the declaration of the loop to:
foreach (int number in numbers)
This is possible because a type that implements IEnumerable allows you to use foreach. As another example, if we had a collection of students:
IEnumerable<Student> students = GetStudents();
We could loop over those like this:
foreach (Student student in students)
Going back to your loop, now that number is an int, we don't have to convert it from an object to an int before we can check if it's even or not. So the loop's code can be simplified to:
foreach (int number in numbers)
{
if (number % 2 == 0)
{
Console.WriteLine("{0} is even", number);
}
}
The main thing to understand is that when you already know what type you'd like to use, you should always use it whenever you can, as it will always simplify the code you write. The complete program would now look like this:
class Program
{
static void Main(string[] args)
{
IEnumerable<int> numbers = Enumerable.Range(1, 100);
foreach (int number in numbers)
{
if (number % 2 == 0)
{
Console.WriteLine("{0} is even", number);
}
}
Console.Read();
}
}
As for the other change I mentioned, your integer generation code could be simplified to:
var numbers = Enumerable.Range(1, 100);
The var keyword is making use of implicit type inference to determine numbers type. Similarly, the loop could also be changed to:
foreach (var number in numbers)
I wouldn't worry about implicit type inference for the moment. I'm mentioning more for the sake of completeness, but you should learn to use the type system properly first.
Your code is almost correct (except for the .Equals("Even") part). Your code inside the foreachcan be simplified to:
Console.WriteLine(number.ToString() + ((Convert.ToInt32(number) % 2) == 0 ? " is even" : ""));
}
Check this code snippets.
class Program
{
static void Main(string[] args)
{
var stringBuilder = new StringBuilder();
var numbers = new List<object>();
numbers = Enumerable.Range(0, 100).Cast<object> ().ToList();
foreach (var number in numbers)
{
if (Convert.ToInt32(number) % 2 == 0)
stringBuilder.Append("EVEN");
else
stringBuilder.Append(number);
}
Console.WriteLine(stringBuilder.ToString());
}
}
Please let me know if this snippets could solve your problems
Related
I have an Extension Method that extract the numbers in a list of strings (bbb1, da21ds, dsa231djsla90 ==> 1, 21, 23190):
public static int[] GetContainedNumbers(this string[] source)
{
if (source == null) throw new ArgumentNullException();
int[] result = new int[] {};
foreach (var s in source)
{
string onlyNumbers = new String(s.Where(Char.IsDigit).ToArray());
if (String.IsNullOrEmpty(onlyNumbers)) throw new ArgumentException();
int extractedNumber = Int32.Parse(onlyNumbers);
result = result.Concat(new int[] { extractedNumber }).ToArray();
}
return result;
}
I need to make a test with NUnit. The request is to make a test with an infinite sequence of strings (a1z, a2z, a3z, ...), but the output only needs to check the first 100 numbers.
Currently I have no idea what I'm supposed to do. My starting idea was to create a test like this:
int[] expectedResult = Enumerable.Range(0, 99).ToArray();
string[] source = new string[] {};
int n = 0;
while (true)
{
if (n == 99) break;
source = source.Concat(new string[] { "a" + n + "z" }).ToArray();
n++;
}
Assert.AreEqual(expectedResult, source.GetContainedNumbers());
But it doesn't really make sense since the array is finite and not infinite.
I don't know what it means to create an infinite list of things and how I should create it nor testing it.
I can edit the Extension Method if needed. Thanks in advance for any help and sorry if my english is quite broken.
The first task is to make the Extension method itself, which I have resolved above. It can be modified, but it must resolve this piece of code (which I can't edit):
foreach (var d in new[] { "1qui7", "q8u8o", "-1024", "0q0ua0" }.GetContainedNumbers())
{
Console.WriteLine("{0}, ", d);
var strings = new [ ] { "1qui7" , " q8u8o " , " −1024" , " 0 q0ua0 " };
}
Expected output: 17, 88, 1024, 0,
I believe the purpose of this exercise is to investigate lazy evaluation.
Currently your method accepts a string[] and returns an int[] - but there's nothing in the question that says it has to do that.
If instead you were to write an extension method accepting an IEnumerable<string> and returning an IEnumerable<int>, then you could accept an infinite sequence of elements and return a corresponding infinite sequence of outputs, that is lazily evaluated: when the caller requests the next output element, you in turn request the next input element, process it, and yield an output. C# makes all of this quite straightforward with iterator blocks.
So I would expect a method like this:
public static IEnumerable<int> GetContainedNumbers(IEnumerable<string> source)
{
foreach (string inputElement)
{
int outputElement = ...; // TODO: your logic here
yield return output;
}
}
Now to test this, you can either use iterator blocks again to generate genuinely infinite sequences, or you could test against an effectively infinite sequence using LINQ, e.g.
IEnumerable<string> veryLargeInput = Enumerable
.Range(0, int.MaxValue)
.Select(x => $"a{x}z");
The truly infinite version might be something like:
IEnumerable<string> infiniteSequence = GetInfiniteSequence();
...
private static IEnumerable<string> GetInfiniteSequence()
{
int value = 0;
while (true)
{
yield return $"x{value}z";
// Eventually this will loop round from int.MaxValue to
// int.MinValue. You could use BigInteger if you really wanted.
value++;
}
}
When testing the result, you'll want to take the first 100 elements of the output. For example:
var input = GetInfiniteSequence(); // Or the huge Enumerable.Range
var output = input.GetContainedNumbers(); // This is still infinite
var first100Elements = output.Take(100).ToList();
// Now make assertions against first100Elements
Is there a simple^ way of getting the value 'null' if an array element does not exist?
For example, in the code below sArray has 3 elements and the first 3 calls to SomeMethod work (prints true), however the 4th call SomeMethod(sArray[3]); gives me an IndexOutOfRangeException. Is there a way to make the 4th call to SomeMethod print false?
static void Main(string[] args)
{
int[] sArray = new int[]{1,2,3};
SomeMethod(sArray[0]);
SomeMethod(sArray[1]);
SomeMethod(sArray[2]);
SomeMethod(sArray[3]);
}
static void SomeMethod(int? s) => Console.WriteLine(s.HasValue);
^Would prefer single line expression
There is a Linq method ElementAtOrDefault
To use it the way you want to (returning null) you will need ti change the underlying type of your array to nullable int:
int?[] sArray = new int?[]{1,2,3};
SomeMethod(sArray.ElementAtOrDefault(1000));
How about an extension method?
public static T? TryGet<T>(this T[] source, int index) where T: struct
{
if (0 <= index && index < source.Length)
{
return source[index];
}
else
{
return null;
}
}
Then you could write:
static void Main(string[] args)
{
int[] sArray = new int[]{1,2,3};
SomeMethod(sArray.TryGet(0));
SomeMethod(sArray.TryGet(1));
SomeMethod(sArray.TryGet(2));
SomeMethod(sArray.TryGet(3));
}
SomeMethod(sArray.Skip(3).Select(z => (int?)z).FirstOrDefault());
is a working replacement of:
SomeMethod(sArray[3]);
The former will call SomeMethod with null (while the latter will throw an exception if the array doesn't have at least 4 entries).
In Skip(3) the 3 can be changed to whatever index you want to retrieve from the array. The Select is needed to project the int into a int? so that FirstOrDefault returns either the 4th element or null.
If you don't want to use LINQ then you could use:
SomeMethod(sArray.Length > 3 ? sArray[3] : (int?)null);
instead.
Or consider using:
foreach (var entry in sArray.Take(4))
{
SomeMethod(entry);
}
to loop through up to 4 elements of the array (it will work fine if there are fewer than 4 - it will just make fewer calls to SomeMethod).
Arrays in C# have a .Length property which you can check before trying to pass an item from one to SomeMethod, and the typical approach is to loop through each element of the array rather than guessing whether or not an index is valid:
for (int i = 0; i < sArray.Length; i++)
{
SomeMethod(sArray[i]);
}
You will not be able to avoid an IndexOutOfRangeException if you reference an index in an array that doesn't exist.
However, if you really want a method with this type of functionality, you could simply modify your existing code to check whether or not the index specified is greater than the length of the array.
Since your array is an int[] (and not an int?[]), all valid indexes will have a value. Also, we can use the ?. to handle cases where the array itself may be null:
private static void SomeMethod(int[] array, int index) =>
Console.WriteLine(index >= 0 && index < array?.Length);
Then in use, instead of passing an array item with an invalid index (which will always throw an IndexOutOfRangeException), you would pass the array itself and the index separately:
static void Main()
{
int[] sArray = new int[] { 1, 2, 3 };
SomeMethod(sArray, 0);
SomeMethod(sArray, 1);
SomeMethod(sArray, 2);
SomeMethod(sArray, 3);
SomeMethod(null, 0);
GetKeyFromUser("\nPress any key to exit...");
}
Output
in this case I'll suggest you to create a extension somewhere in your code like this
static class ArrExt
{
public static int? Get(this int[] arr, int i)
{
return (i >= 0 && i < arr.Length) ? arr[i] : default(int?);
}
}
then you can do this
int[] sArray = new int[] { 1, 2, 3 };
SomeMethod(sArray.Get(0));
SomeMethod(sArray.Get(1));
SomeMethod(sArray.Get(2));
SomeMethod(sArray.Get(3));
okay this is not a single line solution I know, but it's easier for both programmer and computer.
C # code:
I have 20 random numbers between 1-100 in an array and the program should check if every value is unique. Now i should use another method which returns true if there are only unique values in the array and false if there are not any unique values in the array. I would appreciate if someone could help me with this.
bool allUnique = array.Distinct().Count() == array.Count(); // or array.Length
or
var uniqueNumbers = new HashSet<int>(array);
bool allUnique = uniqueNumbers.Count == array.Count();
A small alternative to #TimSchmelters excellent answers that can run a bit more efficient:
public static bool AllUniq<T> (this IEnumerable<T> data) {
HashSet<T> hs = new HashSet<T>();
return data.All(hs.Add);
}
What this basically does is generating a for loop:
public static bool AllUniq<T> (this IEnumerable<T> data) {
HashSet<T> hs = new HashSet<T>();
foreach(T x in data) {
if(!hs.Add(x)) {
return false;
}
}
return true;
}
From the moment one hs.Add fails - this because the element already exists - the method returns false, if no such object can be found, it returns true.
The reason that this can work faster is that it will stop the process from the moment a duplicate is found whereas the previously discussed approaches first construct a collection of unique numbers and then compare the size. Now if you iterate over large amount of numbers, constructing the entire distinct list can be computationally intensive.
Furthermore note that there are more clever ways than generate-and-test to generate random distinct numbers. For instance interleave the generate and test procedure. Once a project I had to correct generated Sudoku's this way. The result was that one had to wait entire days before it came up with a puzzle.
Here's a non linq solution
for(int i=0; i< YourArray.Length;i++)
{
for(int x=i+1; x< YourArray.Length; x++)
{
if(YourArray[i] == YourArray[x])
{
Console.WriteLine("Found repeated value");
}
}
}
I'm asking the user to input 5 numbers and store it into an array so I can send the values in a method and subtract 5 numbers from each array. When I use the:
for(I=0;I<5;I++) {
int[] val = Console.ReadLine();}
It says I can't convert int[] to int. I'm a little rusty in my programming. I also don't know how to send the array values from the main to the method.
You're assigning the string input from the Console to an array of int. This is wrong for two reasons:
int arrays (int[]) are a collection of ints.
The value you're getting from the Console isn't an int and needs to be parsed first.
This is a slight diversion, but I also don't think you should be using an array. Arrays generally have significantly less function in C# than the built-in List<T>. (All the rockstars chime in here) Some people say there's no reason to use arrays at all - I won't go that far, but I think for this use case it'll be a lot easier to just add items to a List than to allocate 5 spaces and initialize values by index.
Either way, you should use int.TryParse(), not int.Parse(), given that you'll immediately get an exception if you don't check if the user input was parseable to int. So example code for taking in strings from the user would look like this:
List<int> userInts = new List<int>();
for (int i = 0; i < 5; i++)
{
string userValue = Console.ReadLine();
int userInt;
if (int.TryParse(userValue, out userInt))
{
userInts.Add(userInt);
}
}
If you'd still like to use the array, or if you have to, just replace List<int> userInts... with int[] userInts = new int[5];, and replace userInts.Add(userInt) with userInts[i] = userInt;.
You initialize the array first
int[] val = new int[5];
and then when you do a for loop:
for (int i=0; i<val.Length; i++)
{
val[i] = int.Parse(Console.ReadLine());
}
Hint: To send the array values from main to the method, just look at how static void main is formed:
static void Main(string[] args)
Meaning main is accepting a string array of of console arguments.
You just need to parse the string being entered from the console to int first.You accept int by doing:
for(int i=0;i<myArray.Length;i++) {
myArray[i] = int.Parse(Console.ReadLine()); //Int32.Parse(Console.ReadLine()) also works
Just like #Furkle said, it is always best to use TryParse() which enables you to perform exception handling. MSDN has a nice tutorial on this.
furkle is correct, it's not working because the console.ReadLine method returns a string, and you can't assign a string to an int array. However, the solution provided is a bit clunky because it only reads one character at a time from the console. It's better to take in all the input at once.
Here is a short console program that
takes in a space separated list of integers from the user
converts the string to a string List using Split(' ').ToList();
Converts the string List to an int List
Reads the contents back to you.
Error handling is included.
static void Main(string[] args){
var intList = new List<int>();
string sUserInput = "";
var sList = new List<string>();
bool validInput = true;
do
{
validInput = true;
Console.WriteLine("input a space separated list of integers");
sUserInput = Console.ReadLine();
sList = sUserInput.Split(' ').ToList();
try
{
foreach (var item in sList) {intList.Add(int.Parse(item));}
}
catch (Exception e)
{
validInput = false;
Console.WriteLine("An error occurred. You may have entered the list incorrectly. Please make sure you only enter integer values separated by a space. \r\n");
}
} while (validInput == false);
Console.WriteLine("\r\nHere are the contents of the intList:");
foreach (var item in intList)
{
Console.WriteLine(item);
}
Console.WriteLine("\r\npress any key to exit...");
Console.ReadKey();
}//end main
If you want to make sure the user only enters a total of 5 integers you can do the DO WHILE loop like this:
do
{
validInput = true;
Console.WriteLine("input a space separated list of integers");
sUserInput = Console.ReadLine();
sList = sUserInput.Split(' ').ToList();
if (sList.Count > 5)
{
validInput = false;
Console.WriteLine("you entered too many integers. You must enter only 5 integers. \r\n");
}
else
{
try
{
foreach (var item in sList) { intList.Add(int.Parse(item)); }
}
catch (Exception e)
{
validInput = false;
Console.WriteLine("An error occurred. You may have entered the list incorrectly. Please make sure you only enter integer values separated by a space. \r\n");
}
}
} while (validInput == false);
for (int i = (int)MY_ENUM.First; i <= (int)MY_ENUM.Last; i++)
{
//do work
}
Is there a more elegant way to do this?
You should be able to utilize the following:
foreach (MY_ENUM enumValue in Enum.GetValues(typeof(MY_ENUM)))
{
// Do work.
}
Enums are kind of like integers, but you can't rely on their values to always be sequential or ascending. You can assign integer values to enum values that would break your simple for loop:
public class Program
{
enum MyEnum
{
First = 10,
Middle,
Last = 1
}
public static void Main(string[] args)
{
for (int i = (int)MyEnum.First; i <= (int)MyEnum.Last; i++)
{
Console.WriteLine(i); // will never happen
}
Console.ReadLine();
}
}
As others have said, Enum.GetValues is the way to go instead.
Take a look at Enum.GetValues:
foreach (var value in Enum.GetValues(typeof(MY_ENUM))) { ... }
The public static Array GetValues(Type enumType) method returns an array with the values of the anEnum enumeration. Since arrays implements the IEnumerable interface, it is possible to enumerate them.
For example :
EnumName[] values = (EnumName[])Enum.GetValues(typeof(EnumName));
foreach (EnumName n in values)
Console.WriteLine(n);
You can see more detailed explaination at MSDN.