I want to create a function which will return the matrix, but I have a problem with limit the time of put the data to console.
public static List<List<int>> CreateMatrix()
{
List<List<int>> matrix = new List<List<int>>();
List<int> row = new List<int>();
do
{
row = Array.ConvertAll<string, int>(Console.ReadLine().Split(" ", StringSplitOptions.RemoveEmptyEntries), int.Parse).OfType<int>().ToList();
matrix.Add(row);
} while (matrix[0].Count == row.Count);
return matrix;
}
I want to create a loop which will accept the row of numbers, but when nothing is put inside the row at least five seconds for example, then the loop should be break
Using one of the examples from This Post, I've created a simple example for you which will add items entered on the console to a List collection. Hopefully it will be a good starting point for you to be able to do what you need.
public static void Main()
{
int waitTimeInSeconds = 10;
List<string> matrix = new();
do
{
var task = Task.Factory.StartNew(Console.ReadLine);
var result = Task.WaitAny(new Task[] { task }, TimeSpan.FromSeconds(waitTimeInSeconds)) == 0
? task.Result : string.Empty;
if (!String.IsNullOrEmpty(result))
{
matrix.Add(result);
}
else
{
break;
}
} while (true);
if (matrix is not null)
{
Console.WriteLine($"# Items Added to Array: {matrix.Count}\n");
foreach (var m in matrix)
{
Console.Write(m);
}
}
}
Reviewing your code however, I'm not sure what you're trying to achieve in your while loop.
Your row variable looks to take the input of the console.ReadLine() and convert it to an integer, but you haven't considered if the input isn't of type integer, as if not, it will cause a System.FormatException.
Secondly, it seems like you're returning a list of list simply because that's the type which Array.ConvertAll().ToList() returns and you want a to return multiple values. I suspect you just want to return the list of values that you've read from the console instead.
Just some food for thought
Related
I'm learning and currently trying to write a simple multiple choice quiz. I am not allowed to write it simply with if else statements.
I'm trying to make it so that it asks the question the user inputs the answer (that's all fine) but a separate class works out if it's right or not.
Where my code has the array with a blank index I'm wondering how after the first iteration it would check the next index when that method was called upon again in the next question. I tried to use a for each but then get an error regarding not every path has an outcome.
private static readonly string[] answerArray = new string[5] { "C", "A", "B", "A", "C" };
public static bool AnswerCalc(string ain)
{
if (ain == answerArray[])
{
Console.WriteLine("Correct");
return true;
}
else
{
Console.WriteLine("Sorry that's wrong");
return false;
}
}
I had it as a bool as that's how I was keeping score.
If you want to check if an array contains an item simply:
var aInArr = arr.Contains("A");
This is a LINQ expression built into .net.
One way to implement this as a non-extension method targeting array is like so:
public bool Contains(string[] arr, string inputStr)
{
for(int i = 0; i < arr.Length; i++)
{
if (item == inputStr[i])
return true;
}
return false;
}
Once it runs out of items in the array it will break out of the for loop curly brackets and return false.
Note: for brevity I reduced the result but the .net way to do this is to use an IEnumerable on a generic input instead of an array and use foreach instead of for.
public static Contains<T>(this IEnumerable<T> input, T compared)
{
foreach (var item in input)
{
if (item == compared)
return true;
}
return false;
}
If you store an integer in the class containing this method, you can increment it at the end of the function call (make sure you reset it to 0 when it reaches the length of the array). Use this integer between the square braces like so: if (ain == answerArray[intValue])
If you need more help then let me know and I'll be happy to update this with more information.
Keep getting the following message when printing a list on console.
System.Collections.Generic.List`1[System.Int32]
This is the console code. It is designed to generate a Fibonacci sequence of a given length. I have tried using the ToString() method, but that doesn't work either. I have built the algorithm in Java so i know that the issue, is fundamentally a C# problem. The issue is resolved if print i print the list elements individually, but i can't print the whole list.
class Program
{
public static void Main(string[] args)
{
Fibonacci fibo = new Fibonacci();
Console.WriteLine(fibo.getSequence(9));
Console.ReadLine();
}
}
class Fibonacci
{
public List<int> getSequence(int length)
{
List<int> results = new List<int>();
results.Add(1);
results.Add(1);
int counter = 0;
while (counter != length - 2)
{
int num1 = results[results.Count - 1];
int num2 = results[results.Count - 2];
results.Add(num1 + num2);
counter++;
}
return results;
}
}
You're returning a List<int>. To print it, you have to e.g. iterate over it
foreach(var i in fibo.getSequence(9)) {
Console.WriteLine(i);
}
Or you can use String.Join()
Console.WriteLine(String.Join(" ", fibo.getSequence(9)));
You are trying to print the object directly to console try iterating over list and print them wherever returned.
for (var item in returned)
Console.WriteLine(item)
if using a custom Type. keep in mind that you have defined its to string method.
Change your Main() to read:
public static void Main(string[] args)
{
Fibonacci fibo = new Fibonacci();
foreach(var element in fibo.getSequence(9))
{
Console.WriteLine(element);
}
Console.ReadLine();
}
Explanation
Look at what you're passing to Console.WriteLine() in your example. getSequence() is returning a list, so you're passing a list to WriteLine(). WriteLine will ToString() on the collection which, by default, will render out the type. If you pass it each individual element (int), it will call ToString() on each one and give you the number.
This is based on the assumption that you want a line per element. If not, look into using String.Join
Resharper constantly complains about this: Possible multiple enumeration of IEnumerable. For example:
private int ParseLoanNumber(IEnumerable<string> lines)
{
var loanNumber = 0;
var item = lines.FirstOrDefault(l => l.StartsWith(" LN# 00"));
if (item != null)
{
loanNumber = item.ParseInt(8, 10).GetValueOrDefault();
}
else
{
item = lines.FirstOrDefault(l => l.StartsWith(" LOAN-NO (CONT'D) 00"));
if (item != null)
{
loanNumber = item.ParseInt(19, 10).GetValueOrDefault();
}
}
// Yada yada...
}
The recommended solution is to convert the enumerable to a list or array, and iterate over that.
This baffles me. You will still be enumerating something, and both types (arrays and lists) implement IEnumerable. So how does this solve anything, or improve performance in any way?
Because you can write this:
public IEnumerable<int> GetNumbersSlowly()
{
for (var i = 0; i < 100; i++)
{
Thread.Sleep(10000); //Or retrieve from a website, etc
yield return i;
}
}
If you use it like this:
var numbers = GetNumbersSlowly();
foreach(var number in numbers) {
//Do something
}
foreach(var number in numbers) {
//Do something
}
It means the work done (the sleep) is done twice for each number. Evaluating the enumerable once and storing it in an array or list means you're sure there's no extra processing being done to return the items.
Since you're taking an IEnumerable<string>, you really don't know that the caller hasn't done the above.
If you think my example might be rare or an edge case, it also applies to things like this:
var someSource = new List<int> { 1, 2, 3, 4, 5 };
var numbers = someSource.Select(s => s * 100000);
Now every time you iterate numbers, you're also re-doing the calculation. In this case it's not much work, by why do it more than you need (and it's not uncommon for it to be non-trivial work).
I'm reading in a text file that contains data for 3D elements and store them in a dictionary dict in C#. The main objects are OPEN_SHELLs and CLOSED_SHELLs. These contain multiple ADVANCED_FACEs. These again contain a single FACE_OUTER_BOUND and multiple FACE_BOUNDs. These again contain more values and so on until there are finally numerical values.
For now I have a class Step that contains
List<List>string>> closedShell; //contains all closed shells with their values
List<List<string>> openShell; //contains all open shells with their values
List<List<string>> closedShellAdvFace; //contains all closed advanced faces...
List<List<string>> openShellAdvFace; //contains all open advanced faces...
...
I iterate through each list to get the next values and so on. Now this doesn't seem really efficient as I'm using duplicate code for closed and open lists.
An examplary code for this:
string closedShellKey = "";
string closedShellValue = "";
string openShellKey = "";
string openShellValue = "";
// For CLOSED_SHELLs
for (int shellListIndex = 0; shellListIndex < stepObj.GetClosedShells().Count; shellListIndex++)
{
for (int valuesCount = 1; valuesCount < stepObj.GetClosedShells()[shellListIndex].Count - 1; valuesCount++)
{
if (dict.ContainsKey(stepObj.GetClosedShells()[shellListIndex][valuesCount]))
{
closedShellKey = stepObj.GetClosedShells()[shellListIndex][valuesCount];
dict.TryGetValue(closedShellKey, out closedShellValue);
stepObj.SetCsAdvFace(SplitValues(closedShellValue));
} else
{
//Throw Exception
}
}
}
// For OPEN_SHELLs
for (int shellListIndex = 0; shellListIndex < stepObj.GetOpenShells().Count; shellListIndex++)
{
for (int valuesCount = 1; valuesCount < stepObj.GetOpenShells()[shellListIndex].Count - 1; valuesCount++)
{
if (dict.ContainsKey(stepObj.GetOpenShells()[shellListIndex][valuesCount]))
{
openShellKey = stepObj.GetOpenShells()[shellListIndex][valuesCount];
dict.TryGetValue(openShellKey, out openShellValue);
stepObj.SetOsAdvFace(SplitValues(openShellValue));
} else
{
//Throw Exception
}
}
}
This goes on for the next values, etc.
What would be a really good and efficient way to implement each of these steps?
Maybe create an openShellObject and a closedShellObject to further seperate?
How would I handle data that contains different data that again contains further different data, etc.?
Hope this is clear enough
First, note that Dictionary.TryGetValue already does the work of Dictionary.ContainsKey so you only need the former.
If I understand this, you need to iterate over multiple collections, applying an operation that varies only in one step, according to each collection category, e.g. closed face, open face, etc. How to separate that step from the iteration code? I'd suggest either Template Method pattern or Method As Parameter (MAP). For this problem I'd probably choose MAP because the collection items vary by category not data type, and probably it means less coding.
In the pseudocode below I've assumed that the final step in each iteration always involves a method like stepObj.SetCsAdvFace that takes a string[] value returned by SplitValues. This is why, in the Apply method below, the parameter method is a delegate that takes a string[] parameter, so it matches either stepObj.SetCsAdvFace or stepObj.SetOsAdvFace, whichever is required for the relevant collection.
private void Apply(List<List<string>> list, Action<string[]> method)
{
foreach (var items in list)
{
for (int valuesIndex = 1; valuesIndex < items.Count - 1; valuesIndex++)
{
var key = items[valuesIndex];
string values;
if (dict.TryGetValue(key, out values))
{
method(SplitValues(values));
}
else
{
//Throw Exception
}
}
}
}
Apply(stepObj.GetClosedShells(), stepObj.SetCsAdvFace);
Apply(stepObj.GetOpenShells(), stepObj.SetOsAdvFace);
...
First get rid of two for loops, use IEnumerable instead:
var allShellKeys = stepObj.GetClosedShells().Union(stepObj.GetOpenShells()).SelectMany(i => i.Skip(1).Take(i.Count() - 2))
Then you can iterate over all values in one loop:
string anyShellValue;
foreach (var anyShellKey in allShellKeys)
{
if (dict.TryGetValue(anyShellKey, out anyShellValue))
{
stepObj.SetCsAdvFace(SplitValues(anyShellValue));
}
else
{
//Throw Exception
}
}
I am new to C# and I ran into the following problem (I have looked for a solution here and on google but was not successful):
Given an array of strings (some columns can possibly be doubles or integers "in string format") I would like to convert this array to an integer array.
The question only concerns the columns with actual string values (say a list of countries).
Now I believe a Dictionary can help me to identify the unique values in a given column and associate an integer number to every country that appears.
Then to create my new array which should be of type int (or double) I could loop through the whole array and define the new array via the dictionary. This I would need to do for every column which has string values.
This seems inefficient, is there a better way?
In the end I would like to do multiple linear regression (or even fit a generalized linear model, meaning I want to get a design matrix eventually) with the data.
EDIT:
1) Sorry for being unclear, I will try to clarify:
Given:
MAKE;VALUE ;GENDER
AUDI;40912.2;m
WV;3332;f
AUDI;1234.99;m
DACIA;0;m
AUDI;12354.2;m
AUDI;123;m
VW;21321.2;f
I want to get a "numerical" matrix with identifiers for the the string valued columns
MAKE;VALUE;GENDER
1;40912.2;0
2;3332;1
1;1234.99;0
3;0;0
1;12354.2;0
1;123;0
2;21321.2;1
2) I think this is actually not what I need to solve my problem. Still it does seem like an interesting question.
3) Thank you for the responses so far.
This will take all the possible strings which represent an integer and puts them in a List.
You can do the same with strings wich represent a double.
Is this what you mean??
List<int> myIntList = new List<int>()
foreach(string value in stringArray)
{
int myInt;
if(Int.TryParse(value,out myInt)
{
myIntList.Add(myInt);
}
}
Dictionary is good if you want to map each string to a key like this:
var myDictionary = new Dictionary<int,string>();
myDictionary.Add(1,"CountryOne");
myDictionary.Add(2,"CountryTwo");
myDictionary.Add(3,"CountryThree");
Then you can get your values like:
string myCountry = myDictionary[2];
But still not sure if i'm helping you right now. Do you have som code to specify what you mean?
I'm not sure if this is what you are looking for but it does output the result you are looking for, from which you can create an appropriate data structure to use. I use a list of string but you can use something else to hold the processed data. I can expand further, if needed.
It does assume that the number of "columns", based on the semicolon character, is equal throughout the data and is flexible enough to handle any number of columns. Its kind of ugly but it should get what you want.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication3
{
class StringColIndex
{
public int ColIndex { get; set; }
public List<string> StringValues {get;set;}
}
class Program
{
static void Main(string[] args)
{
var StringRepresentationAsInt = new List<StringColIndex>();
List<string> rawDataList = new List<string>();
List<string> rawDataWithStringsAsIdsList = new List<string>();
rawDataList.Add("AUDI;40912.2;m");rawDataList.Add("VW;3332;f ");
rawDataList.Add("AUDI;1234.99;m");rawDataList.Add("DACIA;0;m");
rawDataList.Add("AUDI;12354.2;m");rawDataList.Add("AUDI;123;m");
rawDataList.Add("VW;21321.2;f ");
foreach(var rawData in rawDataList)
{
var split = rawData.Split(';');
var line = string.Empty;
for(int i= 0; i < split.Length; i++)
{
double outValue;
var isNumberic = Double.TryParse(split[i], out outValue);
var txt = split[i];
if (!isNumberic)
{
if(StringRepresentationAsInt
.Where(x => x.ColIndex == i).Count() == 0)
{
StringRepresentationAsInt.Add(
new StringColIndex { ColIndex = i,
StringValues = new List<string> { txt } });
}
var obj = StringRepresentationAsInt
.First(x => x.ColIndex == i);
if (!obj.StringValues.Contains(txt)){
obj.StringValues.Add(txt);
}
line += (string.IsNullOrEmpty(line) ?
string.Empty :
("," + (obj.StringValues.IndexOf(txt) + 1).ToString()));
}
else
{
line += "," + split[i];
}
}
rawDataWithStringsAsIdsList.Add(line);
}
rawDataWithStringsAsIdsList.ForEach(x => Console.WriteLine(x));
Console.ReadLine();
/*
Desired output:
1;40912.2;0
2;3332;1
1;1234.99;0
3;0;0
1;12354.2;0
1;123;0
2;21321.2;1
*/
}
}
}