How do I create a subset of an array? - c#

I have 1 array with many string lines.
For every line in that array, if a condition is met,
I have a console app that displays the line from the array, with some modifications (I call this the outputLine).
How do I make an array from the list of outputLines ?
class Program
{
static void Main(string[] args)
{
string[] linesArray = File.ReadAllLines(#"C:\Users\AK1\Desktop\CC2_B.TXT");
int linecount = File.ReadAllLines(#"C:\Users\AK1\Desktop\CC2_B.TXT").Length;
for (int i = 0; i < linecount; i++)
{
if (linesArray[i].Contains("2008/12"))
{
string[] outputArray = linesArray;
string outputLine = "yes " + outputArray[i];
Console.WriteLine(outputLine);
}
}
Console.ReadLine();
}
}

Rather than an array, which has to define its size at declaration in C#, you're looking for a List<string>. You might want to refer to this answer about adding elements to an array to better understand the difference between List and array
Add using System.Collections.Generic at the top of your file and modify your code as such:
class Program
{
static void Main(string[] args)
{
string[] linesArray = File.ReadAllLines(#"C:\Users\AK1\Desktop\CC2_B.TXT");
int linecount = File.ReadAllLines(#"C:\Users\AK1\Desktop\CC2_B.TXT").Length;
List<string> outputLines = new List<string>();
for (int i = 0; i < linecount; i++)
{
if (linesArray[i].Contains("2008/12"))
{
string outputLine = "yes " + linesArray[i];
outputLines.Add(outputLine);
Console.WriteLine(outputLine);
}
}
Console.ReadLine();
}
}
Then if you really need it to be an array (like to pass it to another function), you can call outputLines.ToArray()

why not first filter your lines with desired condition by using linq? then you can output in console.
string[] lines = File.ReadAllLines(#"C:\Users\AK1\Desktop\CC2_B.TXT");
string[] filteredLines = lines.Where(line => line.Contains("2008/12")).ToArray();
foreach(string line in filteredLines){
Console.WriteLine("yes " + line);
}

Declare an array with a capacity of linecount, in case you need to add every single line.
I suppose this is c++? so you can not increase an array size in runtime.
static void Main(string[] args)
{
int outputCounter=0;
.......
if (linesArray[i].Contains("2008/12"))
{
string outputLine = "yes " + outputArray[i];
outputArray[outputCounter]= outputLine;
outputCounter++;
Console.WriteLine(outputLine);
}
}
Update:
For c# just do something like this
static void Main(string[] args)
{
List<string> outputList = new List<string>();
.......
if (linesArray[i].Contains("2008/12"))
{
string outputLine = "yes " + outputArray[i];
outputList.Add(outputLine);
Console.WriteLine(outputLine);
}
}

Try working with Lists instead of arrays if you're wanting to make dynamic additions. For example;
class Program
{
static void Main(string[] args)
{
string[] linesArray = File.ReadAllLines(#"C:\Users\AK1\Desktop\CC2_B.TXT");
int linecount = File.ReadAllLines(#"C:\Users\AK1\Desktop\CC2_B.TXT").Length;
// Delcare your list here
List<string> outputList = new List<string>();
for (int i = 0; i < linecount; i++)
{
if (linesArray[i].Contains("2008/12"))
{
// You can "Add" to lists easily like this
outputList.Add(linesArray[i]);
// This will return you the last item in the list
string outputLine = "yes " + outputList.Last();
Console.WriteLine(outputLine);
}
}
// Then if you specifically want it back to an Array
string[] outputArray = outputList.ToArray();
Console.ReadLine();
}
}
Hope this helps :)

Related

Function that writes out the sum only writes out 0

Problem: The sum writes out as 0. How do i make it so that the function Summa() writes out the actual sum out of the 10 numbers that user writes in?
This is probably extremely simple but im new to this :P
All of the things in the code weren't separate before but i wanted if i could move the sum part to it's own function
using System;
namespace Array
{
class Program
{
static void Main(string[] args)
{
int number;
int[] vektor = new int[10];
for (int i = 0; i < vektor.Length; i++)
{
Console.WriteLine("Enter a number");
number = Convert.ToInt32(Console.ReadLine());
vektor[i] = number;
}
Summa();
}
static void Summa()
{
int sum = 0;
int[] vektor = new int[10];
int i = 0;
sum = sum + vektor[i];
Console.WriteLine("The amount is " + sum);
}
}
}
You are creating a new array called vektor in the Summa() function, instead of using the one created in the main() function. Also you've to iterate through the array to find the sum
Change Summa to :
static void Summa(int[] vektor)
{
int sum = 0;
for(int i=0; i < vektor.Length; i++)
{
sum = sum + vektor[i];
}
Console.WriteLine("The amount is " + sum);
}
And change the function call in the main() to:
Summa(vektor);
You are summing a different array; you'd need to pass the array in:
static void Summa(int[] vektor)
{
int sum = 0;
foreach (var val in vektor)
sum += val;
// ^^^ or just use: var sum = vektor.Sum();
Console.WriteLine("The amount is " + sum);
}
/// ...
Summa(vektor);
So, you're not passing any information to your method "Summa", but you're instead creating a new Array.
So you need to pass the Array from your main method to you "summa" method.
namespace Array
{
class Program
{
static void Main(string[] args)
{
int number;
int[] vektor = new int[3];
for (int i = 0; i < vektor.Length; i++)
{
Console.WriteLine("Enter a number");
number = Convert.ToInt32(Console.ReadLine());
vektor[i] = number;
}
Summa(vektor);
}
static void Summa(int[] vektor)
{
int sum = 0;
foreach (var item in vektor)
{
sum += vektor[item];
}
Console.WriteLine("The amount is " + sum);
}
}
}
Also, using foreach loops will make your life much easier in the future.
https://www.w3schools.com/cs/cs_for_loop.asp
When you're unsure what your program is doing and don't know why it isn't working like it should. Try using the debug feature.
If you're using Visual Studio you can access it by pressing F11.
Lycka till med studierna!

Is there any way to save char Array in For loop?

I want to create a simple hangman and I'm stuck :/.
Here is simple code what detects all chars in the array.
I need some way to save it and then write it.
I add the comment in the code for more readability and where I want to save.
And at the end i need to write it.
Is there anything I could do better in code? I'm a newbie.
public static void Main(string[] args)
{
char[] array;
randomWord = "apple".ToCharArray();
Console.WriteLine(randomWord);
while (guessing == true) {
Console.WriteLine();
userinput = char.Parse(Console.ReadLine());
for (int i = 0; i < randomWord.Length; i++)
{
if (randomWord[i].ToString().Contains(userinput))
{
Console.Write(userinput);
//add to array
enter code here
}
else
{
//add to array
enter code here
Console.Write("_ ");
}
}
//and here Write whole array
for(int g = 0; g < array.Lenght; g++){
Console.Write(array[g]);
}
}
Use a generic list (List<T>) they are more flexible than arrays:
public static void Main(string[] args)
{
List<char> array = new List<char>();
randomWord = "apple".ToCharArray();
Console.WriteLine(randomWord);
while (guessing == true) {
Console.WriteLine();
userinput = char.Parse(Console.ReadLine());
for (int i = 0; i < randomWord.Length; i++)
{
if (randomWord[i].ToString().Contains(userinput))
{
Console.Write(userinput);
//add to array
array.Add(randomWord[i]);
}
else
{
//it's not clear what you want to add to here?
Console.Write("_ ");
}
}
//and here Write whole array
//use a foreach
foreach(char c in array ){
Console.Write(c);
}
//your missing a brace
}
}

Reading text file until a space and storing several values

I am creating an application to read and display Pokemon stats. Currently, I have 6 txt files, one for each stat. I have 6 arrays reading each txt file and displaying each stat in a label.
I want to condense this information into a single text file, splitting each stat by a " " to keep each Pokemon's data on a single line.
Current code if it helps explain the idea better:
using System;
using System.Windows.Forms;
using System.IO;
namespace Pokedex
{
public partial class Pokedex : Form
{
public Pokedex()
{
InitializeComponent();
}
//Read stat data from text files into string arrays
string[] HP = File.ReadAllLines("HP.txt");
string[] Atk = File.ReadAllLines("Atk.txt");
string[] Def = File.ReadAllLines("Def.txt");
string[] SpAtk = File.ReadAllLines("SpAtk.txt");
string[] SpDef = File.ReadAllLines("SpDef.txt");
string[] Spe = File.ReadAllLines("Spe.txt");
private void cbxPokemon_SelectedIndexChanged(object sender, EventArgs e)
{
//Get array index of currently selected Pokemon
int index = cbxPokemon.SelectedIndex;
//Get integer values out of the string arrays for appropriate use
int intHP = int.Parse(HP[index]);
int intAtk = int.Parse(Atk[index]);
int intDef = int.Parse(Def[index]);
int intSpAtk = int.Parse(SpAtk[index]);
int intSpDef = int.Parse(SpDef[index]);
int intSpe = int.Parse(Spe[index]);
//Update labels with stat values in string forme, could also assign intStat.ToString()
lblDexNum.Text = (index + 1).ToString("d3");
lblHP.Text = HP[index];
lblAtk.Text = Atk[index];
lblDef.Text = Def[index];
lblSpAtk.Text = SpAtk[index];
lblSpDef.Text = SpDef[index];
lblSpe.Text = Spe[index];
lblBST.Text = (intHP + intAtk + intDef + intSpAtk + intSpDef + intSpe).ToString();
//Update bar width based on stat value
barHP.Width = intHP;
barAtk.Width = intAtk;
barDef.Width = intDef;
barSpAtk.Width = intSpAtk;
barSpDef.Width = intSpDef;
barSpe.Width = intSpe;
//Disable Previous and Next buttons when they cannot be used
if (index == 0) { btnPrev.Enabled = false; }
else { btnPrev.Enabled = true; }
if (index == cbxPokemon.Items.Count - 1) { btnNext.Enabled = false; }
else { btnNext.Enabled = true; }
}
private void btnPrev_Click(object sender, EventArgs e)
{
cbxPokemon.SelectedIndex -= 1;
}
private void btnNext_Click(object sender, EventArgs e)
{
cbxPokemon.SelectedIndex += 1;
}
}
}
Ideally, the file would contain the 6 stats, for example "100 90 80 70 60 50" on each line, with each of those valued being stored.
Is there a simple way to read until a space, store that value, and keep doing that until the end of the line?
Yes, this is very simple to do. You can use the String.Split() method to break apart the lines into parsable pieces.
You can read the stats file in the same way you are now, except you would only need to read one file instead of six:
string[] lines = File.ReadAllLines("PokemonStats.txt");
Then, inside your cbxPokemon_SelectedIndexChanged method, you can retrieve the stats for a Pokemon like this:
//Get integer values out of the string for appropriate use
string line = lines[index];
string[] parts = line.Split(' ');
int intHP = int.Parse(parts[0]);
int intAtk = int.Parse(parts[1]);
int intDef = int.Parse(parts[2]);
int intSpAtk = int.Parse(parts[3]);
int intSpDef = int.Parse(parts[4]);
int intSpe = int.Parse(parts[5]);
Of course this assumes there will always be exactly 6 integer stats per line and they will all be in a specific order.
Try something like this:
static void Main(string[] args)
{
//list to store stats
List<string[]> pokemonStats = new List<string[]>();
//get a reader on the file
using (StreamReader reader = new StreamReader("TextFile1.txt"))
{
//while we still have lines to read
while (!reader.EndOfStream)
{
//get the line of stats
string line = reader.ReadLine();
//split it on the ' ' character and store it in our list of pokemon stats
pokemonStats.Add(line.Split(' '));
}
}
//we have them all so do something, like print to screen
foreach (string[] pokemon in pokemonStats)
{
foreach (string stat in pokemon)
Console.Write(stat + " ");
Console.WriteLine();
}
Console.ReadLine();
}
Where TextFile1.txt contains; which also happens to be the output...
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
Ideally, the file would contain the 6 stats, for example "100 90 80 70 60 50" on each line, with each of those valued being stored.
So this solution is actually very simple, assuming you have a file that looks like this:
100
90
80
70
60
50
You could write code that looks like this:
public string[] ReadStats(string fileName)
{
return File.ReadAllLines(fileName);
}
This would return:
[ "100", "90", "80", "70", "60", "50" ]
This is obviously an over-simplified version that does not checking on whether the file exists, whether there are more than 6 lines, etc. But it gets the idea across, and you could enhance it to suit your needs.
The answer to your main question:
Is there a simple way to read until a space, store that value, and keep doing that until the end of the line?
This is a bit more complicated, but this should work:
public IEnumerable<string[]> ReadAllPokemonStats(string fileName)
{
List<string[]> allPokemon = new List<string[]>();
string[] allStats = new string[6];
var allText = File.ReadAllText(fileName);
int nextStatIndex = 0;
string thisStat;
for(int i=0; i < allText.Length; i++)
{
var nextChar = allText[i];
if(nextChar == ' ')
{
allStats[nextStatIndex] = thisStat;
nextStatIndex++;
continue;
}
if(nextChar == '\r')
{
allPokemon.Add(allStats);
nextStatIndex = 0;
allStats = new string[6];
continue;
}
thisStat += nextChar.ToString();
}
return allPokemon;
}
Again, the above code is not perfect, for example it reads the entire file into memory so there's a potential attack vector there. It also does not ensure that the stats are actually numeric, but neither did your code (it would just blow up on the int.Parse()). But again, it gives you the general idea. You can see this approach is actually a lot more complex that reading each stat line by line.
I am thinking that each file is a one column file that represents one type of stat. If this is correct, you can try this:
Perhaps creating a class the represents all the stats that you are loading and then treat that as an array or a dictionary to fetch the proper stat or to create a single stat file.
public class PokemonStat
{
public int Hp { get; set; }
public int Atk { get; set; }
public int Def { get; set; }
public int SpAtk { get; set; }
public int SpDef { get; set; }
public int Spe { get; set; }
}
Then in your executing file:
var newPokemanData = new Dictionary<int, PokemonStat>();
var fileNames = new string[] { "Hp.txt", "Atk.txt", "Def.txt", "SpAtk.txt", "SpDef.txt", "Spe.txt" }
foreach (var fileName in fileNames)
{
var lineNumber = 0;
using (var stream = new StreamReader(fileName))
{
while (!stream.EndOfStream)
{
var singleStat = stream.ReadLine();
if (!newPokemanData.Keys.Contains(lineNumber))
{
newPokemanData.Add(lineNumber, new PokemonStat());
}
switch(fileName)
{
case "Hp.txt":
newPokemanData[lineNumber].Hp = int.Parse(singleStat);
break;
case "Atk.txt":
newPokemanData[lineNumber].Atk = int.Parse(singleStat);
break;
case "Def.txt":
newPokemanData[lineNumber].Def = int.Parse(singleStat);
break;
case "SpAtk.txt":
newPokemanData[lineNumber].SpAtk = int.Parse(singleStat);
break;
case "SpDef.txt":
newPokemanData[lineNumber].SpDef = int.Parse(singleStat);
break;
case "Spe.txt":
newPokemanData[lineNumber].Spe = int.Parse(singleStat);
break;
default:
Console.WriteLine("Error");
break;
}
lineNumber++;
}
}
}
using (var unifiedStats = new StreamWriter("unifieldFile.txt"))
{
foreach (var line in newPokemanData.Keys)
{
//write to a file
unifiedStats.WriteLine(newPokemanData[line].Hp.ToString() + " " +
newPokemanData[line].Atk.ToString() + " " +
newPokemanData[line].Def.ToString() + " " +
newPokemanData[line].SpAtk.ToString() + " " +
newPokemanData[line].SpDef.ToString() + " " +
newPokemanData[line].Spe.ToString() + " "
);
}
}
//

Updating a list using a method?

This is a really simple question concerning a method. I'm pretty new to C# and am testing lists. How do I call the method "addTwo" so that it updates every element in the "Marks" list by two? Please note that I've already created this method (scroll down further below the main method). I just want to know how to call it in the main method.
namespace ParallelLists
{
class Program
{
static void Main(string[] args)
{
//create an list of 4 student names
List<string> names = new List<string>(4);
names.Add("Matt");
names.Add("Mark");
names.Add("Luke");
names.Add("John");
//create a list of 4 integers representing marks
List<decimal> marks = new List<decimal>(4);
marks.Add(88m);
marks.Add(90m);
marks.Add(55m);
marks.Add(75m);
Console.WriteLine("the mark of " + names[0] + " is : " + marks[0]);
Console.ReadLine();
//Upgrade everyone by 2 marks
...
}
public List<decimal> addTwo(List<decimal> mark)
{
List<decimal> temp = mark;
for (int i = 0; i < temp.Count; i++)
{
temp[i] += 2m;
}
return temp;
}
}
}
You need to make your method static, since you are accessing on a non object. also you need to update your marks collection with the returned value. You dont actually need to return the List because list is mutable.
class Program
{
static void Main(string[] args)
{
//create an list of 4 student names
List<string> names = new List<string>(4);
names.Add("Matt");
names.Add("Mark");
names.Add("Luke");
names.Add("John");
//create a list of 4 integers representing marks
List<decimal> marks = new List<decimal>(4);
marks.Add(88m);
marks.Add(90m);
marks.Add(55m);
marks.Add(75m);
marks = addTwo(marks);
Console.WriteLine("the mark of " + names[0] + " is : " + marks[0]);
Console.ReadLine();
Console.Read();
}
public static List<decimal> addTwo(List<decimal> mark)
{
List<decimal> temp = mark;
for (int i = 0; i < temp.Count; i++)
{
temp[i] += 2m;
}
return temp;
}
}
if you dont want to return the list, you can do the following:
class Program
{
static void Main(string[] args)
{
//create an list of 4 student names
List<string> names = new List<string>(4);
names.Add("Matt");
names.Add("Mark");
names.Add("Luke");
names.Add("John");
//create a list of 4 integers representing marks
List<decimal> marks = new List<decimal>(4);
marks.Add(88m);
marks.Add(90m);
marks.Add(55m);
marks.Add(75m);
addTwo(marks);
Console.WriteLine("the mark of " + names[0] + " is : " + marks[0]);
Console.ReadLine();
Console.Read();
}
public static void addTwo(List<decimal> mark)
{
List<decimal> temp = mark;
for (int i = 0; i < temp.Count; i++)
{
temp[i] += 2m;
}
}
}
Your list is already getting a reference to 'mark' why return anything when any operation you are doing will operate on that same list.
instead of:
public List<decimal> addTwo(List<decimal> mark)
{
List<decimal> temp = mark;
for (int i = 0; i < temp.Count; i++)
{
temp[i] += 2m;
}
return temp;
}
I would do:
public void addTwo(List<decimal> mark)
{
for (int i = 0; i < mark.Count; i++)
{
temp[i] += 2m;
}
}
Then in your code call is just as
addTwo(mark);
I would rename it to AddTwo to fit normal c# conventions as well.
//Upgrade everyone by 2 marks
var plustwo = addTwo(marks);
Console.WriteLine("the mark of " + names[0] + " is : " + plustwo[0]);
Console.ReadLine();
Note, that you will also need to make AddTwo a static method:
public static List<decimal> addTwo(List<decimal> mark)

How to extgract an integer and a two dimensional integer array from a combination of both in C#

I have an input as
2:{{2,10},{6,4}}
I am reading this as
string input = Console.ReadLine();
Next this input has to be passed to a function
GetCount(int count, int[,] arr)
{
}
How can I do so using C#?
Thanks
You could use RegularExpressions for extracting in an easy way each token of your input string. In the following example, support for extra spaces is included also (the \s* in the regular expressions).
Remember that always is a great idea to give a class the responsibility of parsing (in this example) rather than taking an procedural approach.
All the relevant lines are commented for better understanding.
Finally, i tested this and worked with the provided sample input strings.
using System;
using System.Text.RegularExpressions;
namespace IntPairArrayParserDemo
{
class Program
{
static void Main(string[] args)
{
var input = "2:{{2,10},{6,4}}";
ParseAndPrintArray(input);
var anotherInput = "2 : { { 2 , 10 } , { 6 , 4 } }";
ParseAndPrintArray(anotherInput);
}
private static void ParseAndPrintArray(string input)
{
Console.WriteLine("Parsing array {0}...", input);
var array = IntPairArrayParser.Parse(input);
var pairCount = array.GetLength(0);
for (var i = 0; i < pairCount; i++)
{
Console.WriteLine("Pair found: {0},{1}", array[i, 0], array[i, 1]);
}
Console.WriteLine();
}
}
internal static class IntPairArrayParser
{
public static int[,] Parse(string input)
{
if (string.IsNullOrWhiteSpace(input)) throw new ArgumentOutOfRangeException("input");
// parse array length from string
var length = ParseLength(input);
// create the array that will hold all the parsed elements
var result = new int[length, 2];
// parse array elements from input
ParseAndStoreElements(input, result);
return result;
}
private static void ParseAndStoreElements(string input, int[,] array)
{
// get the length of the first dimension of the array
var expectedElementCount = array.GetLength(0);
// parse array elements
var elementMatches = Regex.Matches(input, #"{\s*(\d+)\s*,\s*(\d+)\s*}");
// validate that the number of elements present in input is corrent
if (expectedElementCount != elementMatches.Count)
{
var errorMessage = string.Format("Array should have {0} elements. It actually has {1} elements.", expectedElementCount, elementMatches.Count);
throw new ArgumentException(errorMessage, "input");
}
// parse array elements from input into array
for (var elementIndex = 0; elementIndex < expectedElementCount; elementIndex++)
{
ParseAndStoreElement(elementMatches[elementIndex], elementIndex, array);
}
}
private static void ParseAndStoreElement(Match match, int index, int[,] array)
{
// parse first and second element values from the match found
var first = int.Parse(match.Groups[1].Value);
var second = int.Parse(match.Groups[2].Value);
array[index, 0] = first;
array[index, 1] = second;
}
private static int ParseLength(string input)
{
// get the length from input and parse it as int
var lengthMatch = Regex.Match(input, #"(\d+)\s*:");
return int.Parse(lengthMatch.Groups[1].Value);
}
}
}
Not to do your work for you, you will first have to parse the whole string to find the individual integers, either using regular expressions or, as I would do it myself, the string.Split method. Then parse the substrings representing the individual integers with the int.Parse or the int.TryParse methods.
I doubt you're going to get a serious parsing answer for your custom format. If you NEED to have the value inputted that way, I'd look up some info on regular expressions. If that's not powerful enough for you, there are some fairly convienient parser-generators you can use.
Alternatively, the much more realistic idea would be something like this:
(NOTE: Haven't tried this at all... didn't even put it in VS... but this is the idea...)
int rows = 0;
string rowsInput = "";
do {
Console.Write("Number of rows:");
rowsInput = Console.ReadLine();
} while (!Int32.TryParse(rowsInput, out rows);
int columns = 0;
string columnsInput = "";
do {
Console.Write("Number of columns:");
string columnsInput = Console.ReadLine();
} while (!Int32.TryParse(columnsInput, out columns);
List<List<int>> values = new List<List<int>>();
for (int i = 0; i < rows; i++)
{
bool validInput = false;
do {
Console.Write(String.Format("Enter comma-delimited integers for row #{0}:", i.ToString()));
string row = Console.ReadLine();
string[] items = row.split(',');
int temp;
validInput = (items.Length == columns) && (from item in items where !Int32.TryParse(item, out temp) select item).count() == 0;
if (validInput)
{
values.add(
(from item in items select Convert.ToInt32(item)).ToList()
);
}
} while (!validInput);
}

Categories