Efficiently fetching information from .xml files and make them available to other methods - c#

first I'm sorry if I mix up some terminology or overlooked some very obvious method, but I'm quite new in C# and OOP in general and this is my project I "self learn" c# with at the moment. That's why I will share larger parts of my code to hopefully iron out some unclarities.
I wan't to get information from an .xml file and use those information in various different methods. For this I found a solution which I implemented and works fine, but is kind of clunky.
I use this Method to read out everything I need from the XML:
class ReadAndLoad
{
public List<CharacterAttributes> FetchAttributes(string userPath)
{
// Declare a new XML Document
XmlDocument XmlDoc = new XmlDocument();
// Try to open the XML file
try
{
Console.WriteLine("\nNow Loading: {0}\n", userPath);
XmlDoc.Load(userPath);
}
// Catch "File Not Found" errors
catch (System.IO.FileNotFoundException)
{
Console.WriteLine("No file found!");
Environment.Exit(1);
}
// Catch Argument Exceptions
catch (System.ArgumentException)
{
Console.WriteLine("Invalid path detected!");
Environment.Exit(1);
}
// Catach all other errors, and print them to console.
catch (Exception err)
{
Console.WriteLine("An Exception has been caught:");
Console.WriteLine(err);
Environment.Exit(1);
}
// Declare the xpath for finding objects inside the XML file
XmlNodeList XmlDocNodes = XmlDoc.SelectNodes("/character/attributes/attribute");
// Define a new List, to store the objects we pull out of the XML
List<CharacterAttributes> attributeList = new List<CharacterAttributes>();
// Loop through the nodes, extracting Person information.
// We can then define a person object and add it to the list.
foreach (XmlNode node in XmlDocNodes)
{
int tempValue = int.Parse(node["totalvalue"].InnerText);
CharacterAttributes obj = new CharacterAttributes(node["name"].InnerText, tempValue);
attributeList.Add(obj);
}
for (int i = 0; i < attributeList.Count; i++)
{
Console.WriteLine(attributeList[i].AttributeName);
Console.WriteLine(attributeList[i].TotalValue);
}
return attributeList;
}
Created a "Character class" that has all attributes in an constructor
class Character
{
//Attribute Fields
public int Body { get; set; }
public int Agility { get; set; }
public int Reaction { get; set; }
public int Strength { get; set; }
public int Willpower { get; set; }
public int Logic { get; set; }
public int Intuition { get; set; }
public int Charisma { get; set; }
public int Edge { get; set; }
public int Essence { get; set; }
public int Resonance { get; set; }
public int Magic { get; set; }
//Attribute Constructor
public Character(int xmlBody, int xmlAgility, int xmlReaction, int xmlStrength, int xmlIntuition, int xmlCharisma, int xmlLogic, int xmlWillpower, int xmlEdge, int xmlMagic, int xmlResonance, int xmlEssence)
{
this.Body = xmlBody;
this.Agility = xmlAgility;
this.Reaction = xmlReaction;
this.Strength = xmlStrength;
this.Intuition = xmlIntuition;
this.Charisma = xmlCharisma;
this.Logic = xmlLogic;
this.Willpower = xmlWillpower;
this.Edge = xmlEdge;
this.Essence = xmlEssence;
this.Resonance = xmlResonance;
this.Magic = xmlMagic;
}
And to create a character I created this Method which takes the list provided by ReadAndLoad.FetchAttributes and feeds them in the constructor
class CreateCharacters
{
public Character CreateCharacterFromXML(string userPath)
{
ReadAndLoad readAndLoad = new ReadAndLoad();
List<CharacterAttributes> attributeList = new List<CharacterAttributes>();
attributeList = readAndLoad.FetchAttributes(userPath);
int bod = attributeList[0].TotalValue;
int agi = attributeList[1].TotalValue;
int rea = attributeList[2].TotalValue;
int str = attributeList[3].TotalValue;
int cha = attributeList[4].TotalValue;
int intuition = attributeList[5].TotalValue;
int log = attributeList[6].TotalValue;
int wil = attributeList[7].TotalValue;
int edg = attributeList[8].TotalValue;
int mag = attributeList[9].TotalValue;
int res = attributeList[11].TotalValue;
int ess = attributeList[12].TotalValue;
Character myCharacter = new Character(bod, agi, rea, str, cha, intuition, log, wil, edg, mag, res, ess);
return myCharacter;
}
}
I feel like there is a more elegant and efficient way to do this, which is easier to expand upon with more data from the same XML. Because at the moment if I would like to introduce some other data I would have to create a new ReadAndLoad Method, the new class for that information, expand the character class and constructor and add all that in the CreateCharacter Method.
Someone pointed me towards xml deserialization, but I wasn't able to make the examples given here work (I tried deserialization from TextReader).
The xml I tried to deserialize / get information from doesn't provide a schema as url, because of that I don't really know how to deserialize it. Given below is the start of the xml.
After some searching I found the schema .xsd that probably gives me the correct schema.
Deserialisazion is sadly not possible at the moment because of an error in the .xsd I can't find.
The .xsd I try to use for deserialization references another .xsd which seems to contain errors, which leads to some elements not being declared.
InteliSense sadly doesn't provide any information regarding that error.

The super-simple way to do this is to copy an XML document to your clipboard and in a C# code file Paste XML as Classes:

Related

How to create a Class List with different numbers of inputs in C#

I'm working on my first real c# project and I have faced a problem with my way of creating List based on a Class, which I have no idea how to solve.
I’m trying to write some code, which takes an input file (txt/csv) of multiple constructions with multiple layers, put it into my program, and later write the constructions into a new txt/csv file.
When having the same numbers of layers, it works fine. But when the constructions have different numbers of layers it causes trouble and I get a “System.IndexOutOfRangeException”.
My question is: Can I make the Class which I’m basing my List on, dynamic (I don’t know if it is the technical term), so it work with different numbers of inputs? Both when Adding the construction to the program and when I write it to a new file?
My code is:
class Program
{
static void Main(string[] args)
{
// Filepath for the input and output file
string filePathIn_constructions = #"C:\Library\Constructions.txt";
string filePathOut = #"C:\Library\EPlus_Inputfile.txt";
// Creating a list of constructions based on the class. The list is made from the file "filePathIn_constructions"
List<Construction> allConstructions = new List<Construction>();
List<string> lines_constructions = File.ReadAllLines(filePathIn_constructions).ToList(); // add it to a list
// Adding all the data from the fil to the variable "allConstructions"
foreach (var line in lines_constructions)
{
string[] entries = line.Split(',');
Construction newConstruction = new Construction();
newConstruction.EIndex = entries[0];
newConstruction.Name = entries[1];
newConstruction.Layer1 = entries[2];
newConstruction.Layer2 = entries[3];
newConstruction.Layer3 = entries[4];
newConstruction.Layer4 = entries[5];
newConstruction.Layer5 = entries[6];
allConstructions.Add(newConstruction); // Add it to our list of constructions
}
List<string> output = new List<string>();
foreach (var x in allConstructions) // Printing the new
{
output.Add($"{x.EIndex}, {x.Name}, {x.Layer1}, {x.Layer2}, {x.Layer3}, {x.Layer4}, {x.Layer5}");
}
File.WriteAllLines(txtFilePathOut, output);
}
}
My Class for the Constructions is
public class Construction
{
public string EIndex { get; set; }
public string Name { get; set; }
public string Layer1 { get; set; }
public string Layer2 { get; set; }
public string Layer3 { get; set; }
public string Layer4 { get; set; }
public string Layer5 { get; set; }
}
An example of a input/output file could be
Construction,ConcreteWall,Concrete;
Construction,Brickwall1,Birck,Isulation,Brick;
Construction,Brickwall2,Birck,AirGap,Isulation,Brick;
Construction,Wood/Concrete Wall,Wood,Isulation,Concrete,Gypson;
Construction,Wood Wall,Wood,AirGap,Gypson,Isulaiton,Gypson;
I hope someone can help. Thanks.
Edit: I have to be able to excess the construction Name seperatly, because i'm using it to do some sorting of the.
public class Construction
{
public string EIndex { get; set; }
public string Name { get; set; }
public List<string> Layers { get; set; } = new List<string>();
}
foreach (var line in lines_constructions)
{
string[] entries = line.Split(',');
Construction newConstruction = new Construction();
newConstruction.EIndex = entries[0];
newConstruction.Name = entries[1];
for (int i=2; i < entries.Length; i++) {
newConstruction.Layers.Add(entries[i]);
}
allConstructions.Add(newConstruction);
}
foreach(var x in allConstuctions) {
File.AppendAllText(output, $"{x.EIndex}, {x.Name}, {string.Join(", ", x.Layers)}");
}
It is because you are trying to reach a cell of an array that doesn't exist (documentation)
In your input/output file you have lines that have between 3 and 7 values, and you are building an array entries out of those values. This means that you will have arrays with between 3 and 7 cells
The problem is that right after creating those arrays you try to access on every array the cells 0, 1, 2... up to the 7th, even for arrays that have only 3 cells!
What you could do to fix this in a simple way is to add columns to have the same number of separator on each lines (you defined the separator of your lines as column with line.Split(',')). This way, every arrays that you will create will always have 7 cells, even if the value inside is null

Looping through a string array to create class variables of those strings

So I have this code in a .cs file called SchoolData that has a class and a list.
public static List<YearGroupsData> yearGroupsDataList = new List<YearGroupsData>();
public class YearGroupsData
{
public int id { get; set; }
public int year { get; set; }
public string groupName { get; set; }
public int subject { get; set; }
}
However, I'm trying to use a loop in another .cs script that does a web connection and gets the data from the website, I haven't included the connection info or some of the script for that as this isn't the part going wrong...
private IEnumerator ViewYearGroups()
{
//Some code for connection here
yield return viewYearGroups;
string yearGroupsDataString = viewYearGroups.text;
yearGroups = yearGroupsDataString.Split(';');
foreach (string yearGroup in yearGroups)
{
YearGroupsData yearGroupsData = new YearGroupsData()
{
id = Int32.Parse(GetDataValue(yearGroup, "Id:")),
year = Int32.Parse(GetDataValue(yearGroup, "Year:")),
groupName = GetDataValue(yearGroup, "GroupName:"),
subject = Int32.Parse(GetDataValue(yearGroup, "Subject:")),
};
SchoolData.yearGroupsDataList.Add(yearGroupsData);
}
}
The GetDataValue is the part that is messing up. It gives me ArgumentOutOfRangeException and I'm not sure why. It works if I'm not using it in a loop, I've tried a for loop as well and still the same, anyone know what's happening?
public string GetDataValue(string data, string index)
{
string value = data.Substring(data.IndexOf(index) + index.Length);
if (value.Contains("|"))
{
value = value.Remove(value.IndexOf("|"));
}
return value;
}
Add a try catch in your GetDataValue() method to help with debugging. If it works without the foreach loop, then my guess is one of the string objects you are iterating over is different than what you may be expecting.
https://msdn.microsoft.com/en-us/library/system.argumentoutofrangeexception(v=vs.110).aspx
try
{
string value = data.Substring(data.IndexOf(index) + index.Length);
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
Where I used the .Split to divide the string at each semicolon was the issue. The string I was splitting had a space after the last semicolon which was creating an empty index from that. I used
yearGroups = yearGroups.Take(yearGroups.Count() - 1).ToArray();
to remove the last index that was empty. The trycatch method helped me find this, thanks.
the ArgumentOutOfRangeException happen when the value of an argument is outside the allowable range of values as defined by the invoked method
try this:
string value = data.Substring(data.IndexOf(index) + index.Length - 1 );

Storing DataGrid in List

With my program I'm trying to automatize another program of which there can be multiple instances. I've already written functionality that will watch the processlist and detect all processes of the program that I want to automatize.
It will store some basic informations about found instances into this ConcurrentDictionary which has its ProcessId as key and the class ProgramToWatch as value:
public static ConcurrentDictionary<int, ProgramToWatch> ProgramToWatchDictionary = new ConcurrentDictionary<int, ProgramToWatch>();
public class ProgramToWatch
{
public string ListItemName { get; set; }
public Process BEProcess { get; set; }
public string BEMainWindowTitle { get; set; }
public Application BEApplication { get; set; }
public Window BEWindow { get; set; }
public bool isLoggedIn { get; set; }
public List<ProgramToWatchDataGrid> BEDataGrid = new List<ProgramToWatchDataGrid>();
}
Now the part I am having problems with. The program I want to watch has a DataGridView which I want to copy into my dictionary. For this I have the BEDataGrid List. The list is using this class as its type:
public class ProgramToWatchDataGrid
{
public int ListID { get; set; }
public string Name { get; set; }
public string Mail { get; set; }
}
Now to store it, I create another instance of the ProgramToWatchDataGrid (called updateGrid), write all the data I read into it, and place this into my Dictionary (I simplified). To do this, I iterate through the DataGrid (first while loop), row for row and copy the updateGrid to my Dictionary - in the second while loop I display the values to verify:
public void ReadDataGridView(int ProcessId)
{
ProgramToWatchDataGrid updateGrid = new ProgramToWatchDataGrid();
//read and store every row
int i=0;
while(i<=totalRowsInGrid)
{
updateGrid.ListId = DataGrid.Rows[i].Cells[0].Value;
updateGrid.Name = DataGrid.Rows[i].Cells[1].Value;
updateGrid.Mail = DataGrid.Rows[i].Cells[2].Value;
ProgramToWatchDictionary[ProcessID].BEDataGrid.Insert(i, updateGrid);
Display(ProgramToWatchDictionary[ProcessID].BEDataGrid[i].Mail);
}
Display("Elements: " + ProgramToWatchDictionary[ProcessID].BeDataGrid.Count);
//display every rows mail
i=0;
while(i<=totalRowsInGrid)
{
Display("HI: " + ProgramToWatchDictionary[ProcessID].BEDataGrid[i].Mail);
i++;
}
}
The way I understand it, the Information rows I read should now be located in ProgramToWatchDictionary[ProcessID].BEDataGrid[accordingRow] because I inserted the Information at that place.
The strange thing is, that this output will be produced:
[01:19] christoferlindstrm#yahoo.com
[01:19] eliseisaksson#yahoo.com
[01:19] peter#pan.com
[01:19] Elements: 3
[01:19] HI: peter#pan.com
[01:19] HI: peter#pan.com
[01:19] HI: peter#pan.com
So right after I've inserted it, the List contains the right value. But after it will always be the last value that was read? Why does this happen and how can I fix this?
Some help would be greatly appreciated!
Got it.
You should create the instance of the object to be added in the while, otherwise you are using only one instance which happens to get different values in your cycle. And of course it will end up with the last value you have inserted.
public void ReadDataGridView(int ProcessId)
{
ProgramToWatchDataGrid updateGrid = null;
//read and store every row
int i=0;
while(i<=totalRowsInGrid)
{
//create a new instance
updateGrid = new ProgramToWatchDataGrid();
updateGrid.ListId = DataGrid.Rows[i].Cells[0].Value;
updateGrid.Name = DataGrid.Rows[i].Cells[1].Value;
updateGrid.Mail = DataGrid.Rows[i].Cells[2].Value;
ProgramToWatchDictionary[ProcessID].BEDataGrid.Insert(i, updateGrid);
Display(ProgramToWatchDictionary[ProcessID].BEDataGrid[i].Mail);
}
Display("Elements: " + ProgramToWatchDictionary[ProcessID].BeDataGrid.Count);
//display every rows mail
i=0;
while(i<=totalRowsInGrid)
{
Display("HI: " + ProgramToWatchDictionary[ProcessID].BEDataGrid[i].Mail);
i++;
}
}

Variable not returning actual values

I want correctly return some variables (arrays)
kazkas.Ads[n]; (n = how many ads are)
kazkas.Ads[n].id;
kazkas.Ads[n].Days[m].Stats.Clicks; // every day have his own clicks
kazkas.Ads[n].Days[m].Stats.Impresons; // every day have his own impresions
from this method and use these variables in other class.
public static void GetAdsStats(string Ticket, DateTime start, DateTime end, int CamId)
{
var client = new CampaignStatsServiceClient();
var id = new CampaignIdFilter();
id.CampaignId = CamId;
var statsdata = new GetAdStatsData();
var kazkas = new Campaign();
kazkas = client.GetAdStats(Ticket, new GetAdStatsData
{
IdFilter = id,
StartDate = start,
EndDate = end
});
long AllClicks = 0;
long AllImpresions = 0;
int reklamos = kazkas.Ads.Length;
long[] statistikaClikai = new long[reklamos];
long[] statistikaImpresions = new long[reklamos];
for (int i = 0; i < reklamos; i++)
{
int dienos = kazkas.Ads[i].Days.Length;
for (int lop = 0; lop < dienos; lop++)
{
AllClicks = AllClicks + kazkas.Ads[i].Days[lop].Stats.Clicks;
AllImpresions = AllImpresions + kazkas.Ads[i].Days[lop].Stats.Impressions;
}
statistikaClikai[i] = AllClicks;
statistikaImpresions[i] = AllImpresions;
}
}
I know that void type can't return anything, but this how I know that my method works ( from debugging). Like you see I was trying do that with for loop. Here i have 9 Ads and every ad have one day.
Like I says I want return every Ads id[in array], and every days.stats.impresions and days.stats.click
how can I do that ? Ore how return more variables/arrays from method to other class, I am using webservises, so i cant use database ore something like that.
As can be seen by the downvotes of the question, you need to design the return value and then code against it.
Your query almost does it (now):
kazkas.Ads[n]; (n = how many ads are)
kazkas.Ads[n].id;
kazkas.Ads[n].Days[m].Stats.Clicks; // every day have his own clicks
kazkas.Ads[n].Days[m].Stats.Impressions; // every day have his own impressions
Your existing code show this should be expanded to include:
kazkas.Ads[n].Total.Clicks;
kazkas.Ads[n].Total.Impressions;
So now you're ready to design. First you want a Stat Class that just contains CLicks and Impressions:
public class Stat
{
public long Impressions { get; set; }
public long Clicks { get; set; }
}
An optimisation here may be to use a struct, but I won't go into that.
As you currently have defined it each Day has just a Stats property:
public class DayStat
{
public Stat Stats { get; set; }
}
Now finally we can define the top level AdStat:
public class AdStat
{
public int id { get; set; }
public DayStat Day[];
public Stat Total { get; set; }
}
Etc... There's further issues here, such as ensuring arrays are created and Stat instances are never null (which is why making some of these classes structs is an option). But I'm really a VB programmer so I'll stop here before I get caught typing crap into the SO IDE :-)
Create a class or struct with members you need
public class Stat
{
public int Id { get; set; }
public long Clicks { get; set; }
...
}
Change the signature of your method from void GetAdsStats to IEnumberable<Stat> GetAdsStats and either return a collection of stats or use yield keyword to return the stat object.
Also if you do not want your method to return anything (return type void) do not use a name starting with Get.
Example:
public static IEnumerable<Stat> GetAdsStats(...)
{
...
var statList = new List<Stat>();
for (int i = 0; i < reklamos; i++)
{
var stat = new Stat();
statList.Add(stat);
int dienos = kazkas.Ads[i].Days.Length;
for (int lop = 0; lop < dienos; lop++)
{
AllClicks = AllClicks + kazkas.Ads[i].Days[lop].Stats.Clicks;
AllImpresions = AllImpresions + kazkas.Ads[i].Days[lop].Stats.Impressions;
}
stat.Clicks = AllClicks;
stat.Impression = AllImpresions;
}
return statList;
}
Change your void to the type you want to return, say Campaign, and return the appropriate variable. The variables you define in your method, only live in your method and are not accessible from another method or class.

How to shuffle multiple related arrays?

I have some unusual I need to do. I am wondering if anyone can think of an easy
way to make the change that I need. What I have is a
public class Report
{
public string[] Text { get; set; }
public string[] Image { get; set; }
public string[] Explanation { get; set; }
}
The report class can have any number of Texts, Images and Explanations and the size of each array is always the consistent but maybe be different for each report instance.
What I need to do is to be able to sort the array elements in a random order. So for example I might have
Report.Text[0] = "text0";
Report.Text[1] = "text1";
Report.Text[2] = "text2";
Report.Image[0] = "img0";
Report.Image[1] = "img1";
Report.Image[2] = "img2";
Report.Explanation[0] = "exp0";
Report.Explanation[1] = "exp1";
Report.Explanation[2] = "exp2";
then after sorting
Report.Text[0] = "text2";
Report.Text[1] = "text0";
Report.Text[2] = "text1";
Report.Image[0] = "img2";
Report.Image[1] = "img0";
Report.Image[2] = "img1";
Report.Explanation[0] = "exp2";
Report.Explanation[1] = "exp0";
Report.Explanation[2] = "exp1";
Can anyone think of a simple way to do this? All I can think of is that I need to create a
new temporary object of the same size and do some kind of swapping. But I am not sure how
to randomize. The reason I am asking is just in case someone has had this need in the past.
I would strongly recommend that you refactor this to create a single class to encapsulate the { Text, Image, Explanation } tuple. At that point, the code will be cleaner and it'll be trivial to reorder the values. Heck, you may not even need a Report type at that point... you may just be able to have a List<ReportItem> or whatever. You'd only need a separate Report type if you wanted to add extra behaviour or data to tie things together.
(As an aside, I hope you don't really have public fields for these to start with...)
If you then have a question around shuffling a single collection, a modified Fisher-Yates shuffle is probably the easiest approach. You could do this with the multiple arrays as well, but it wouldn't be nice - and would have to be specific to Report... whereas you could easily write a generic Fisher-Yates implementation based on IList<T>. If you search on Stack Overflow, you should easily be able to find a few existing implementations :)
If you choose to change your class to the following:
public class Report
{
public string Text { get; set; }
public string Image { get; set; }
public string Explanation { get; set; }
}
You could then do this using an extension method:
(See answer on this SO question)
Then call it this way:
List<Report> reports = new List<Report> { /* create list of reports */ }
Random rnd = new Random();
foreach (Report r in reports.Shuffle(rnd)) {
/* do something with each report */
}
Why don't you create a class
public class Report
{
public string Text { get; set; }
public string Image { get; set; }
public string Explanation { get; set; }
}
and then create a List of those objects and manage it through the list properties:
IList<Report> yourList = new List<Report>()
Here is my solution
class StringWrapper
{
public int Index;
public string Str;
}
public string[] MixArray(string[] array)
{
Random random = new Random();
StringWrapper[] wrappedArray = WrapArray(array);
for (int i = 0; i < wrappedArray.Length; i++)
{
int randomIndex = random.Next(0, wrappedArray.Length - 1);
wrappedArray[i].Index = randomIndex;
}
Array.Sort(wrappedArray, (str1, str2) => str1.Index.CompareTo(str2.Index));
return wrappedArray.Select(wrappedStr => wrappedStr.Str).ToArray();
}
private StringWrapper[] WrapArray(string[] array)
{
int i = 0;
return array.Select(str => new StringWrapper {Index = ++i, Str = str}).ToArray();
}
Then you can call MixArray for each Report object for each property you wand to randomize.
I am not sure I am fond of this direction, but ...
To do exactly what you ask (the law, not the spirit of the law), you will have to add additional arrays and pull items over. In addition, for each array, you will need a List or similar to store the items you have already randomly pulled over. After that, things are simple. Use the Random class to create random numbers, check if the item has already been moved (using the List), if not store the result in the new array/list, add the value to your List to make sure you do not move the same item twice. Once everything is moved, set this new array to the old array.
Now, what is the business reason for randomizing? That might affect whether or not this is a good idea.
ADDED:
After examination of skeet's response, here is a way to solve this if you can use the following type of class:
public class Report {
public string Text { get; set; }
public string Image { get; set; }
public string Explanation { get; set; }
}
Here is one "down and dirty" type of sort:
private static SortedList<int, Report> SortRandomly(List<Report> reports)
{
Random rnd = new Random((int)DateTime.Now.Ticks);
List<int> usedNumbers = new List<int>();
SortedList<int, Report> sortedReports = new SortedList<int, Report>();
int maxValue = reports.Count;
foreach(Report report in reports)
{
bool finished = false;
int randomNumber = 0;
//Get unique random (refactor out?)
while(!finished)
{
randomNumber = rnd.Next(0, maxValue);
if(!usedNumbers.Contains(randomNumber))
{
finished = true;
usedNumbers.Add(randomNumber);
}
}
sortedReports.Add(randomNumber, report);
}
return sortedReports;
}
Note, you can also work to keep the sort in order and randomly picking from the original list, which means you can, in theory, keep it as a list.
private static List<Report> SortRandomly(List<Report> reports)
{
Random rnd = new Random((int)DateTime.Now.Ticks);
List<Report> outputList = new List<Report>();
List<int> usedNumbers = new List<int>();
int maxValue = reports.Count-1;
while(outputList.Count < reports.Count)
{
int randomNumber = rnd.Next(0, maxValue);
if(!usedNumbers.Contains(randomNumber))
{
outputList.Add(reports[randomNumber]);
}
}
return outputList;
}
Even better, consider sorting the list of numbers first and then grabbing the reports, in an order manner. Once again, the above are down and dirty implementations and using the specific requirements will certainly refine the algorithms.

Categories