I am working on a project and I've got stuck :(.... I have 9 (nine) functions with the name:
getM1(), getM2(), getM3(), getM4()....getM5(). And all of these functions return a value.
Now I need to make a loop which checks the value of these functions. Something like this:
public void show()
{
for (int i = 1; i <= 9; i++)
{
if (obj.getM[i]() == 1)
{
.......;
}
}
}
Of course it shows me an error because the getM doesn't contain any index..
And I wanted to ask you, can you help me with this? Or does anybody have another idea how could I check all getM() functions?
Create an array of Func<int> delegates and use it to access your methods:
var functions = new Func<int>[9];
functions[0] = getM1;
functions[1] = getM2;
functions[2] = getM3;
// (...)
for (int i = 0; i <= 9; i++)
{
if (functions[i]() == 1)
{
;
}
}
What about putting the functions into an Array:
var functionList = new [] { obj.getM1, obj.getM2, ... };
And then loop at it
foreach (var f in functionList)
{
if (f() == 1)
...
}
Replace the methods with this:
int getM(int index)
If this and the other solutions suggested really don't make any sense, you can do what you want using reflection:
var t = obj.GetType();
for (int i = 1; i <= 9; i++)
{
var m = t.GetMethod("getM" + i);
int result = (int)m.Invoke(obj, null);
}
Make an array of Func<T>, where T is the return type of your functions. Then you would be able to call your functions more or less the way you described in your code.
For example, if your functions return int, you can do this:
Func<int>[] ems = new Func<int>[] {
() => obj.getM1(), () => obj.getM2(), () => obj.getM3()
, () => obj.getM4(), () => obj.getM5(), () => obj.getM6()
, () => obj.getM7(), () => obj.getM8(), () => obj.getM9()
};
foreach (Func<int> em in ems)
{
if (em() == 1)
{
.......;
}
}
public void Show()
{
Func<int>[] arr = new[]
{
obj.GetM1,
obj.GetM2,
...
};
foreach(Func<int> func in arr)
{
if (func() == 1)
{
//
}
}
}
You could store all of these methods in a list, loop over the list an execute them.
var funcList = new List<Func<int>>{ getM1, getM2, ... };
Then you can loop over the list and execute each method.
foreach(var func in funList)
{
if(func() == 1)
...
}
Related
This one should not be too hard but my mind seems to be having a stack overflow (huehue). I have a series of Lists and I want to find all permutations they can be ordered in. All of the lists have different lengths.
For example:
List 1: 1
List 2: 1, 2
All permutations would be:
1, 1
1, 2
In my case I don't switch the numbers around. (For example 2, 1)
What is the easiest way to write this?
I can't say if the following is the easiest way, but IMO it's the most efficient way. It's basically a generalized version of the my answer to the Looking at each combination in jagged array:
public static class Algorithms
{
public static IEnumerable<T[]> GenerateCombinations<T>(this IReadOnlyList<IReadOnlyList<T>> input)
{
var result = new T[input.Count];
var indices = new int[input.Count];
for (int pos = 0, index = 0; ;)
{
for (; pos < result.Length; pos++, index = 0)
{
indices[pos] = index;
result[pos] = input[pos][index];
}
yield return result;
do
{
if (pos == 0) yield break;
index = indices[--pos] + 1;
}
while (index >= input[pos].Count);
}
}
}
You can see the explanation in the linked answer (shortly it's emulating nested loops). Also since for performace reasons it yields the internal buffer w/o cloning it, you need to clone it if you want store the result for later processing.
Sample usage:
var list1 = new List<int> { 1 };
var list2 = new List<int> { 1, 2 };
var lists = new[] { list1, list2 };
// Non caching usage
foreach (var combination in lists.GenerateCombinations())
{
// do something with the combination
}
// Caching usage
var combinations = lists.GenerateCombinations().Select(c => c.ToList()).ToList();
UPDATE: The GenerateCombinations is a standard C# iterator method, and the implementation basically emulates N nested loops (where N is the input.Count) like this (in pseudo code):
for (int i0 = 0; i0 < input[0].Count; i0++)
for (int i1 = 0; i1 < input[1].Count; i1++)
for (int i2 = 0; i2 < input[2].Count; i2++)
...
for (int iN-1 = 0; iN-1 < input[N-1].Count; iN-1++)
yield { input[0][i0], input[1][i1], input[2][i2], ..., input[N-1][iN-1] }
or showing it differently:
for (indices[0] = 0; indices[0] < input[0].Count; indices[0]++)
{
result[0] = input[0][indices[0]];
for (indices[1] = 0; indices[1] < input[1].Count; indices[1]++)
{
result[1] = input[1][indices[1]];
// ...
for (indices[N-1] = 0; indices[N-1] < input[N-1].Count; indices[N-1]++)
{
result[N-1] = input[N-1][indices[N-1]];
yield return result;
}
}
}
Nested loops:
List<int> listA = (whatever), listB = (whatever);
var answers = new List<Tuple<int,int>>;
for(int a in listA)
for(int b in listB)
answers.add(Tuple.create(a,b));
// do whatever with answers
Try this:
Func<IEnumerable<string>, IEnumerable<string>> combine = null;
combine = xs =>
xs.Skip(1).Any()
? xs.First().SelectMany(x => combine(xs.Skip(1)), (x, y) => String.Format("{0}{1}", x, y))
: xs.First().Select(x => x.ToString());
var strings = new [] { "AB", "12", "$%" };
foreach (var x in combine(strings))
{
Console.WriteLine(x);
}
That gives me:
A1$
A1%
A2$
A2%
B1$
B1%
B2$
B2%
I made the following IEnumerable<IEnumerable<TValue>> class to solve this problem which allows use of generic IEnumerable's and whose enumerator returns all permutations of the values, one from each inner list. It can be conventiently used directly in a foreach loop.
It's a variant of Michael Liu's answer to IEnumerable and Recursion using yield return
I've modified it to return lists with the permutations instead of the single values.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Permutation
{
public class ListOfListsPermuter<TValue> : IEnumerable<IEnumerable<TValue>>
{
private int count;
private IEnumerable<TValue>[] listOfLists;
public ListOfListsPermuter(IEnumerable<IEnumerable<TValue>> listOfLists_)
{
if (object.ReferenceEquals(listOfLists_, null))
{
throw new ArgumentNullException(nameof(listOfLists_));
}
listOfLists =listOfLists_.ToArray();
count = listOfLists.Count();
for (int i = 0; i < count; i++)
{
if (object.ReferenceEquals(listOfLists[i], null))
{
throw new NullReferenceException(string.Format("{0}[{1}] is null.", nameof(listOfLists_), i));
}
}
}
// A variant of Michael Liu's answer in StackOverflow
// https://stackoverflow.com/questions/2055927/ienumerable-and-recursion-using-yield-return
public IEnumerator<IEnumerable<TValue>> GetEnumerator()
{
TValue[] currentList = new TValue[count];
int level = 0;
var enumerators = new Stack<IEnumerator<TValue>>();
IEnumerator<TValue> enumerator = listOfLists[level].GetEnumerator();
try
{
while (true)
{
if (enumerator.MoveNext())
{
currentList[level] = enumerator.Current;
level++;
if (level >= count)
{
level--;
yield return currentList;
}
else
{
enumerators.Push(enumerator);
enumerator = listOfLists[level].GetEnumerator();
}
}
else
{
if (level == 0)
{
yield break;
}
else
{
enumerator.Dispose();
enumerator = enumerators.Pop();
level--;
}
}
}
}
finally
{
// Clean up in case of an exception.
enumerator?.Dispose();
while (enumerators.Count > 0)
{
enumerator = enumerators.Pop();
enumerator.Dispose();
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
You can use it directly in a foreach like this:
public static void Main(string[] args)
{
var listOfLists = new List<List<string>>()
{
{ new List<string>() { "A", "B" } },
{ new List<string>() { "C", "D" } }
};
var permuter = new ListOfListsPermuter<string>(listOfLists);
foreach (IEnumerable<string> item in permuter)
{
Console.WriteLine("{ \"" + string.Join("\", \"", item) + "\" }");
}
}
The output:
{ "A", "C" }
{ "A", "D" }
{ "B", "C" }
{ "B", "D" }
I Have An Array,for example
string[] stArr= new string[5] { "1#3", "19#24", "10#12", "13#18", "20#21" };
i want to sort this array on
3-1=2;
24-19=5;
12-10=2;
18-13=5;
21-20=1;
and the sorting result should be like
string[] stArr= new string[5] { "20#21", "1#3", "10#12", "13#18", "20#21" };
I have to find the solution for all possible cases.
1>length of the array is not fixed(element in the array)
2>y always greater than x e.g x#y
3> i can not use list
You can use LINQ:
var sorted = stArr.OrderBy(s => s.Split('#')
.Select(n => Int32.Parse(n))
.Reverse()
.Aggregate((first,second) => first - second));
For Your Case:
stArr = stArr.OrderBy(s => s.Split('#')
.Select(n => Int32.Parse(n))
.Reverse()
.Aggregate((first,second) => first - second)).ToArray();
try this
string[] stArr = new string[5] { "1#3", "19#24", "10#12", "13#18", "20#21" };
Array.Sort(stArr, new Comparison<string>(compare));
int compare(string z, string t)
{
var xarr = z.Split('#');
var yarr = t.Split('#');
var x1 = int.Parse(xarr[0]);
var y1 = int.Parse(xarr[1]);
var x2 = int.Parse(yarr[0]);
var y2 = int.Parse(yarr[1]);
return (y1 - x1).CompareTo(y2 - x2);
}
Solving this problem is identical to solving any other sorting problem where the order is to be specified by your code - you have to write a custom comparison method, and pass it to the built-in sorter.
In your situation, it means writing something like this:
private static int FindDiff(string s) {
// Split the string at #
// Parse both sides as int
// return rightSide-leftSide
}
private static int CompareDiff(string a, string b) {
return FindDiff(a).CompareTo(FindDiff(b));
}
public static void Main() {
... // Prepare your array
string[] stArr = ...
Array.Sort(stArr, CompareDiff);
}
This approach uses Array.Sort overload with the Comparison<T> delegate implemented in the CompareDiff method. The heart of the solution is the FindDiff method, which takes a string, and produces a numeric value which must be used for comparison.
you can try the following ( using traditional way)
public class Program
{
public static void Main()
{
string[] strArr= new string[5] { "1#3", "19#24", "10#12", "13#18", "20#21" };
var list = new List<Item>();
foreach(var item in strArr){
list.Add(new Item(item));
}
strArr = list.OrderBy(t=>t.Sort).Select(t=>t.Value).ToArray();
foreach(var item in strArr)
Console.WriteLine(item);
}
}
public class Item
{
public Item(string str)
{
var split = str.Split('#');
A = Convert.ToInt32(split[0]);
B = Convert.ToInt32(split[1]);
}
public int A{get; set;}
public int B{get; set;}
public int Sort { get { return Math.Abs(B - A);}}
public string Value { get { return string.Format("{0}#{1}",B,A); }}
}
here a working demo
hope it will help you
Without LINQ and Lists :) Old School.
static void Sort(string [] strArray)
{
try
{
string[] order = new string[strArray.Length];
string[] sortedarray = new string[strArray.Length];
for (int i = 0; i < strArray.Length; i++)
{
string[] values = strArray[i].ToString().Split('#');
int index=int.Parse(values[1].ToString()) - int.Parse(values[0].ToString());
order[i] = strArray[i].ToString() + "," + index;
}
for (int i = 0; i < order.Length; i++)
{
string[] values2 = order[i].ToString().Split(',');
if (sortedarray[int.Parse(values2[1].ToString())-1] == null)
{
sortedarray[int.Parse(values2[1].ToString())-1] = values2[0].ToString();
}
else
{
if ((int.Parse(values2[1].ToString())) >= sortedarray.Length)
{
sortedarray[(int.Parse(values2[1].ToString())-1) - 1] = values2[0].ToString();
}
else if ((int.Parse(values2[1].ToString())) < sortedarray.Length)
{
sortedarray[(int.Parse(values2[1].ToString())-1) + 1] = values2[0].ToString();
}
}
}
for (int i = 0; i < sortedarray.Length; i++)
{
Console.WriteLine(sortedarray[i]);
}
Console.Read();
}
catch (Exception ex)
{
throw;
}
finally
{
}
I want to compute rank of element in an IEnumerable list and assign it to the member. But below code works only when called 1st time. 2nd time call starts from last rank value. So instead of output 012 and 012, I'm getting 012 and 345
class MyClass
{
public string Name { get; set; }
public int Rank { get; set; }
}
public void SecondTimeRankEvaluvate()
{
MyClass[] myArray = new MyClass[]
{
new MyClass() { Name = "Foo" },
new MyClass() { Name = "Bar" },
new MyClass() { Name = "Baz" }
};
int r = 0;
var first = myArray.Select(s => { s.Rank = r++; return s; });
foreach (var item in first)
{
Console.Write(item.Rank);
}
// Prints 012
Console.WriteLine("");
foreach (var item in first)
{
Console.Write(item.Rank);
}
// Prints 345
}
I understand that the variable r is being captured (closure) and reused when called 2nd time. I don't want that behavior. Is there any clean way to compute rank and assign it?
Also r variable (in actual code) isn't in the same scope where foreach loop is present. It is in a function which returns var first
var first = myArray.Select((s, i) => { s.Rank = i; return s; });
LINQ uses lazy evaluation and runs the Select part every time you use myArray.
You can force evaluation to happen only once by storing the result in a List.
Change
var first = myArray.Select(s => { s.Rank = r++; return s; });
to
var first = myArray.Select(s => { s.Rank = r++; return s; }).ToList();
Another way would be to join myArray with a new sequence using Zip every time, like this
var first = myArray.Zip(Enumerable.Range(0, int.MaxValue), (s, r) =>
{
s.Rank = r;
return s;
});
You shouldn't use LINQ if you're not querying the collection.
To update each item in an array, use a for loop:
for (int i = 0; i < myArray.Length; i++)
{
myArray[i].Rank = i;
}
To update each item in an enumerable, use a foreach loop:
int r = 0;
foreach (var item in myArray)
{
item.Rank = r++;
}
I have done some research prior to and have found some great articles but I can't seem to tailor any of the solutions for my given problem. From the research done, I believe the best method of going about this problem would be to use recursion. I have made an example using some generic classes but essentially my problem is I have approximately 10 classes that I can have in a list. I might have only one of these classes and I might have all ten. I am ultimately finding the best combination of "items" (which all inherit from item) for a given problem. I think this would be fairly easy except for I have to deal with creating the combinations before each test.
Below is some sample code using only two classes. If recursion is not the best way to approach this problem then please correct as needed. How might I convert this to be used for any number of items that are needed to test with?
Edited: As some have pointed out my example code is the iterative solution however it is only useful if I have two items. Therefore, I need to define a recursive function to solve the problem based upon the number of for loops needed upon runtime.
-Chance
Research:
C#: N For Loops
Arbitrary number of nested-loops?
Number of nested loops at runtime
static void Main(string[] args)
{
List<Item> myItem = new List<Item>();
int numberItem1 = 0, numberItem2 = 0;
foreach (var item in myItem)
{
if (item.GetType() == typeof(Item1))
{
numberItem1++;
}
else if (item.GetType() == typeof(Item2))
{
numberItem2++;
}
}
List<Item> testingItems = new List<Item>();
//FirstItem
for (int a = 0; a < numberItem1; a++)
{
for (int b = 0; b <= a; b++)
{
testingItems.Add(new Item1 { });
}
//DoTest()
testingItems.Clear();
//Second Item
for (int c = 0; c < numberItem2; c++)
{
for (int d = 0; d <= a ; d++)
{
testingItems.Add(new Item1 { });
}
for (int e = 0; e <= c; e++)
{
testingItems.Add(new Item2 { });
}
//DoTest()
testingItems.Clear();
}
}
}
Non-recursive solution.
IEnumerable<List<Item>> TestLists(List<Item> fullList)
{
List<Type> types = fullList.Select(i => i.GetType()).Distinct().ToList();
List<Item> testList = new List<Item> { (Item)Activator.CreateInstance(types[0]) };
yield return testList;
bool finished = false;
while (!finished)
{
bool incremented = false;
int i = 0;
while (i < types.Count && !incremented)
{
if (testList.Where(t => t.GetType() == types[i]).Count() <
fullList.Where(t => t.GetType() == types[i]).Count())
{
testList.Add((Item)Activator.CreateInstance(types[i]));
incremented = true;
}
else
{
testList = testList.Where(t => t.GetType() != types[i]).ToList();
i++;
}
}
if (incremented)
{
yield return testList;
}
else
{
finished = true;
}
}
}
Usage:
foreach (var partList in TestLists(myListToTest))
{
DoTest(partList);
}
I think the following should work.
This requires you to build a stack of the item types you want to test, and a stack of the number of each present in the original list, with the two stacks in sync with each other.
The input List parameter should be an empty list.
void RecursiveTest(List<Item> testingItems, Stack<Type> itemTypes, Stack<int> itemCounts)
{
if (itemTypes.Count == 0) { return; }
Type thisType = itemTypes.Pop();
int thisCount = itemCounts.Pop();
List<Item> addedItems = new List<Item>();
for (int i = 0; i <= thisCount; i++)
{
if (i > 0)
{
Item thisItem = (Item)Activator.CreateInstance(thisType);
testingItems.Add(thisItem);
addedItems.Add(thisItem);
}
if (itemTypes.Count == 0)
{
DoTest(testingItems);
}
else
{
RecursiveTest(testingItems, itemTypes, itemCounts);
}
}
foreach(Item addedItem in addedItems)
{
testingItems.Remove(addedItem);
}
itemTypes.Push(thisType);
itemCounts.Push(thisCount);
}
Note: This code doesn't output/test lists that don't contain at least one of each item type.
Second note: This now includes the missing cases. It will, however, also test the empty list.
EDIT
This code should generate all the possible test permutations for the list of items + the maximum number of each item that should appear in each test.
EXAMPLE: myItem = Item1 Item1 Item2 Item2 Item3
tests = 1,0,0; 2,0,0; 0,1,0; 1,1,0; 2,1,0; 0,2,0; 1,2,0; 2,2,0; 0,0,1; 1,0,1; 2,0,1; 0,1,1; 1,1,1; 2,1,1; 0,2,1; 1,2,1; 2,2,1
List<Item> myItem = new List<Item>();
List<Type> myOrder = new List<Item>();
Dictionary<Type, int> myCount = new Dictionary<Type, int>();
foreach (var item in myItem)
{
if (myCount.ContainsKey(item.GetType()))
{
myCount[item.GetType()]++;
}
else
{
myOrder.Add(item.GetType());
myCount.Add(item.GetType(), 1);
}
}
List<Item> testingItems = new List<Item>();
int[] testingCounts = new int[myCount.Count];
while(IncrementCounts(testingCounts, myOrder, myCount)) {
for(int x=0; x<testingCounts.length; x++) {
AddInstances( testingItems, myOrder[x], testingCounts[x] );
}
// doTest()
testingItems.Clear();
}
// count permutations using the maxima
// EXAMPLE: maxima [2, 2, 2]
// 1,0,0; 2,0,0; 0,1,0; 1,1,0; 2,1,0; 0,2,0; 1,2,0; 2,2,0; 0,0,1; 1,0,1; 2,0,1 etc..
public static bool IncrementCounts(int[] counts, List<Type> order, Dictionary<Type, int> maxima) {
for(int x=0; x<counts.length; x++) {
if(counts[x] + 1 <= maxima[order[x]]) {
counts[x]++;
return true;
} else {
counts[x] = 0;
}
}
return false; // overflow, so we're finished
}
public static void AddIstances(List<Item> list, Type type, int count) {
for(int x=0; x<count; x++) {
list.Add( Convert.ChangeType( Activator.CreateInstance(type), type ) );
}
}
Please note the above code was written inside the browser window and is untested, so syntax errors may exist.
In PHP I can do this:
$list = array("element1", "element2");
foreach ($list as $index => $value) {
// do stuff
}
In C# i can write:
var list = new List<string>(){ "element1", "element2" };
foreach (var value in list)
{
// do stuff ()
}
But how can I access the index-value in the C# version?
Found multiple solutions on: foreach with index
I liked both JarredPar's solution:
foreach ( var it in list.Select((x,i) => new { Value = x, Index=i }) )
{
// do stuff (with it.Index)
}
and Dan Finch's solution:
list.Each( ( str, index ) =>
{
// do stuff
} );
public static void Each<T>( this IEnumerable<T> ie, Action<T, int> action )
{
var i = 0;
foreach ( var e in ie ) action( e, i++ );
}
I chose Dan Finch's method for better code readability.
(And I didn't need to use continue or break)
I'm not sure it's possible to get the index in a foreach. Just add a new variable, i, and increment it; this would probably be the easiest way of doing it...
int i = 0;
var list = new List<string>(){ "element1", "element2" };
foreach (var value in list)
{
i++;
// do stuff ()
}
If you have a List, then you can use an indexer + for loop:
var list = new List<string>(){ "element1", "element2" };
for (int idx=0; idx<list.Length; idx++)
{
var value = list[idx];
// do stuff ()
}
If you want to access index you should use for loop
for(int i=0; i<list.Count; i++)
{
//do staff()
}
i is the index