Return List With Multiple Elements - c#

I'm struggling getting my head around returning a List that has multiple elements (PHP background - I'd use arrays for this in PHP).
I have a large string that I'm parsing in a WHILE loop. I want to return a List with pairs of elements. I've tried something like this:
static public List<string> getdata(string bigfile)
{
var data = new List<string>[] { new List<string>(), new List<string>() }; // create list to hold data pairs
While (some stuff)
{
// add element pair to List<data>
data[0].Add(this); // add element to list - 'this' is declared and assigned (not shown)
data[1].Add(that); // add element to list - 'that' is declared and assigned (not shown)
}
return data???; // <<-- This is where I'm failing. I can, of course, return just one of the elements, like return data[0];, but I can't seem to get both elements (data[0] and data[1]) together.
} // end getdata
I've reviewed some answers, but I'm missing something. I've tried several things syntactically for the return value, but no luck. Any help would be greatly appreciated. I hate asking questions, but I've spent some time on this and I'm just not finding what I want.

Change method declaration to:
static public List<string>[] getdata(string bigfile)

try with
static public List<string>[] getdata(string bigfile)
{
....
}
Or
But if you need to return list of string array, then change the method as
static public List<string[]> getdata(string bigfile)
{
List<string[]> data= new List<string[]>();
While (some stuff)
{
data.Add(this);
data.Add(that);
}
return data;
}

The problem there is you are returning a Collection of List so the return type is mismatching. Try this one,
var data = new List<string>();
while (some stuff)
{
data.Add("test0");
data.Add("test1");
}
return data;

I want to return a List with pairs of elements
If you want pairs, use pairs:
static public List<Tuple<string, string>> getdata(string bigfile)
{
var data = new List<Tuple<string, string>>(); // create list to hold data pairs
while (some stuff)
{
// add element pair
data.Add(Tuple.Create(a, b)); // 'a' is declared and assigned (not shown)
// 'b' is declared and assigned (not shown)
}
return data;
}

Related

How to get values from web.config app key to a list

I have the following in my web.config:
<add key="someValuestoReturn" value="60,59,58,57,56"/>
I want to return a list of this integer values into my my method but i'm having a difficult to call the list of the values from the web.config:
Private int GetValues(){
var _list = System.Configuration.ConfigurationManager.AppSettings["someValuestoReturn"].ToList(); //<< doesn't work
return _list
}
What would be the best way to achieve this?
Thank you
I might suggest you to solve this on another way..
lets first create an a empty list of a strings which we are going later to put into an array:
After that we need to find your key and we need to get values from a key into our new created list, but we must take care about spliting because your values are comma separated, so check my code below:
List<string> values = new List<string>();
foreach (string key in ConfigurationManager.AppSettings)
{
if (key.StartsWith("someValuestoReturn"))
{
string value = ConfigurationManager.AppSettings[key].Split(',');
values.Add(value);
}
}
string[] myValuesfromWebConfig = values.ToArray();
And that's it, you get all of your values stored in a array called myValuesfromWebConfig
And if you want something else than a string, just change your list/array type from string to int for example..
As you can see I included
string value = ConfigurationManager.AppSettings[key].Split(',');
HERE MORE ABOUT Split method
because your values are comma separated, and I guess you would like to add them to a array/list separately.. :)
Thanks
EDIT:
Because of your error that you wrote in comment, we can skip adding it to an a array, simply delete that line, you will have your values stored in list values anyway, so at the end it migth look like this:
List<string> values = new List<string>();
foreach (string key in ConfigurationManager.AppSettings)
{
if (key.StartsWith("someValuestoReturn"))
{
string value = ConfigurationManager.AppSettings[key].Split(',');
values.Add(value);
}
}
Now if you need to read that values or do whatever you want with them, you can loop throught them and that's it, for example:
foreach(var item in values)
{
//Do whatever you want with your item
}
A string is returned not a List.
For a List use:
var _list = System.Configuration.ConfigurationManager.AppSettings["someValuestoReturn"].Split(",");
System.Configuration.ConfigurationManager.AppSettings["someValuestoReturn"].Split(',');
it will return a string array

Add list to another one - nested list

I would like to add some list to another list.
The result should looks like a main list contains nested list elements.
MainList:
[0]InnerList:
[0]some values
[1]some values
[1]InnerList:
[0]some values
[1]some values
I try to do this this way:
list.Add(new List<myClass>().Add(innerList));
but I've got an error message
Split it up, add does not return the list.
List<List<String>> inner = new List<List<String>>();
List<String> leaves = new List<String>();
leaves.Add( "some string" );
inner.Add( leaves );
list.Add( inner );
Try to use the list constructor instead of the Add method. Because the Add method returns void.
list.Add(new List<myClass>(innerList));
or if innerList is already of type List<myClass> then you can do:
list.Add(innerList);
List of elements of type myClass is List<myClass> so list of such lists is List<List<myClass>>. Here is a simple example how to create and populate such list of lists in one line (I used fictional type C):
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var list = new List<List<C>>{
new List<C>{
new C(1),
new C(2)
},
new List<C>{
new C(3),
new C(4)
}
};
Console.WriteLine((list[0][0]).Value);
Console.WriteLine((list[0][1]).Value);
Console.WriteLine((list[1][0]).Value);
Console.WriteLine((list[1][1]).Value);
}
}
public class C
{
public int Value;
public C(int val)
{
this.Value = val;
}
}
This will give you output:
1
2
3
4

Passing a List into a method, modify the list within the method without affecting 'original'

Sorry if the subject seems vague, I tried summing it up as best I can without knowing the exact terminology of what I'm trying to achieve.
Essentially I have a list and then I call a method
public List<int> myList;
void Start () {
myList = new List<int>();
myList.Add (1);
myList.Add (2);
doSomething(myList);
foreach (int i in myList){
print (i);
}
}
In my method I'd like to do this (for example)
public void doSomething (List<int> myPassedList)
{
int A = 5;
myPassList.Add (A);
//... And then some other cool code with this modified list
}
However, I dont want the original list changed, I want it exactly as it was. Essentially when I pass the list into the method I'd like a duplicate of the list, which is then made new each time the method is called.
I want to see the console print '1' then '2'
but it will print '1', '2' and '5'
Hopefully this all makes sense! Thanks very much in advance for any help
Jim
List is a reference type so when you pass myPassedList as an argument to doSomething you are modifying the original list.
You have two options, either call ToList() or create a new list, as an example:
public void doSomething (List<int> myPassedList)
{
List<int> newList = myPassedList.ToList();
int A = 5;
newList.Add(A);
//... And then some other cool code with this modified list
}
The original list myList will then only return 1 and 2.
If you write a method that works with a list but will not modify that list, then you should document this by code with
public void doSomething ( IEnumerable<int> myPassedValues )
{
List<int> newList = myPassedValues.ToList();
int A = 5;
newList.Add(A);
//... And then some other cool code with this modified list
}
Now you and all others will know, just by reading the declaration that the passed list will not be modified in this method.
Inside your doSomething() method, create a duplicate list by:
var newList = new List<int>(myPassedList);
int A = 5;
newList.Add (A);
myPassedList will not be affected
You can simply copy all the items to a new list.
public void doSomething (List<int> myPassedList)
{
List<int> list = myPassedList.GetRange(0, myPassedList.Count);
}
Simply you can clone the original list in the function
public void doSomething (List<int> myPassedList)
{
List<int> clonedList = myPassedList;
// doing something here with clonedList
}

How to "Dequeue" Element from a List?

I have a List of cards called _deck:
private List<String> _deck = new List<String> {"2h", "3h", "4h", ... }
And then I want to remove a card from the List and save into a variable. I'm trying to do:
String p1FirstCard = _deck.RemoveAt(0);
but I'm getting the error
Cannot convert type void to String
In C# List is there something like push/pop but which does that at the "head" or "start" of the List? (Push/pop works at the "tail" or "end" of the list.)
If not, how should I do remove the first element but save it in a variable?
If you want to dequeue the first element, you could simply use a Queue<T>.
class Program
{
static void Main(string[] args)
{
var _deck = new Queue<String>();
_deck.Enqueue("2h");
_deck.Enqueue("3h");
_deck.Enqueue("4h");
_deck.Enqueue("...");
var first = _deck.Dequeue(); // 2h
first = _deck.Dequeue(); // 3h
}
}
If you want to pop the last element, you could use a Stack<T>.
class Program
{
static void Main(string[] args)
{
var _deck = new Stack<String>();
_deck.Push("2h");
_deck.Push("3h");
_deck.Push("4h");
_deck.Push("...");
var first = _deck.Pop(); // ...
first = _deck.Pop(); // 4h
}
}
You can do it in two steps:
String p1FirstCard = _deck[0];
_deck.RemoveAt(0);
You can write your own extension helper method (I added an index to Pop, as #Fredou suggested:
static class ListExtension
{
public static T PopAt<T>(this List<T> list, int index)
{
T r = list[index];
list.RemoveAt(index);
return r;
}
}
and then call
String p1FirstCard = _deck.PopAt(0);
P.S. The name can be a bit confusing. Pop usually removes the last element, not the first one.
Building on AlexD's answer, I added a couple more extension methods:
public static class ListExtensionMethods
{
public static T PopAt<T>(this List<T> list, int index)
{
var r = list[index];
list.RemoveAt(index);
return r;
}
public static T PopFirst<T>(this List<T> list, Predicate<T> predicate)
{
var index = list.FindIndex(predicate);
var r = list[index];
list.RemoveAt(index);
return r;
}
public static T PopFirstOrDefault<T>(this List<T> list, Predicate<T> predicate) where T : class
{
var index = list.FindIndex(predicate);
if (index > -1)
{
var r = list[index];
list.RemoveAt(index);
return r;
}
return null;
}
}
If you want a direct equivalent to pop(), you'll have to write your own, because I don't think a List has a "Remove from end and return". However, there are both the Queue (first in, first out) and the Stack (first in, last out) classes instead of just a List.
There's also the LinkedList class which lets you add to or remove from both the beginning or the end, but the provided RemoveFirst() and RemoveLast() methods don't automatically return the item being removed - you'd need to write an extension method like AlexD's to do that.
All of these deal with removing things from the beginning or the end of the list. If you just want to remove an arbitrary item from the middle of a List, there's always List.Remove(item) which removes a specific item from the list (rather than by position).
private List<String> _deck = new List<String> {"2h", "3h", "4h", ... }
//Save into variable first
String p1FirstCard = _deck[0];
//Now just remove it
_deck.RemoveAt(0);
RemoveAt(int) doesn't return anything.

Remove item from List and get the item simultaneously

In C# I am trying to get an item from a list at a random index. When it has been retrieved I want it to be removed so that it can't be selected anymore. It seems as if I need a lot of operations to do this, isn't there a function where I can simply extract an item from the list? the RemoveAt(index) function is void. I would like one with a return value.
What I am doing:
List<int> numLst = new List<int>();
numLst.Add(1);
numLst.Add(2);
do
{
int index = rand.Next(numLst.Count);
int extracted = numLst[index];
// do something with extracted value...
numLst.removeAt(index);
}
while(numLst.Count > 0);
What I would like to do:
List<int> numLst = new List<int>();
numLst.Add(1);
numLst.Add(2);
do
{
int extracted = numLst.removeAndGetItem(rand.Next(numLst.Count));
// do something with this value...
}
while(numLst.Count > 0);
Does such a "removeAndGetItem" function exist?
No, as it's a breach of pure function etiquette, where a method either has a side effect, or returns a useful value (i.e. not just indicating an error state) - never both.
If you want the function to appear atomic, you can acquire a lock on the list, which will stop other threads from accessing the list while you are modifying it, provided they also use lock:
public static class Extensions
{
public static T RemoveAndGet<T>(this IList<T> list, int index)
{
lock(list)
{
T value = list[index];
list.RemoveAt(index);
return value;
}
}
}
public static class ListExtensions
{
public static T RemoveAndGetItem<T>(this IList<T> list, int iIndexToRemove}
{
var item = list[iIndexToRemove];
list.RemoveAt(iIndexToRemove);
return item;
}
}
These are called extension methods, call as new List<T>().RemoveAndGetItem(0).
Things to consider in the extension method
Exception handling with the index that you pass, check that the index is withing 0 and the count of the list before doing this.

Categories

Resources