Comparison process with enum element values - c#

Enum A
{ a = 10, a1 = 35, ....}
Enum B
{ b = 5, b1 = 20, ..... }
How can I get the int values ​​of any two of the two enum class elements? To compare with these values ​​and destroy the smaller one.

Sorry. Maybe this is what you're looking for?
enumA.CompareTo(enumB) > 0 ? "A is greater than B" : "B is greater than or equal to A";
enumA.CompareTo(enumB) = 0 ? "A is equal to B" : "A is not equal to B";
This should compare two Enum instances (enumA and enumB), and execute the code inserted in place of the strings.

Take this console app as an example to obtain the lowest int from your enum type:
using System;
using System.Linq;
using System.Collections.Generic;
namespace ConsoleApp1 {
class Program {
enum Colors {
blue = 1,
orange = 2,
purple = 3
}
enum Stages {
level1 = 35,
level2 = 62,
level3 = 13
}
public static int getMinEnumValue(Type enumType) {
Array values = Enum.GetValues(enumType);
List<int> intList = ((int[])values).ToList();
int minValue = intList.Min();
return minValue;
}
static void Main(string[] args) {
int minStagegInt = getMinEnumValue(typeof(Stages));
int minColorInt = getMinEnumValue(typeof(Colors));
Console.WriteLine($"Min stage int: {minStagegInt}, which is: {Enum.GetName(typeof(Stages), minStagegInt)}");
Console.WriteLine($"Min color int: {minColorInt}, which is: {Enum.GetName(typeof(Colors), minColorInt)}");
Console.ReadLine();
//keyValue anonymous type
var myInstance1 = new[] { new { a = 10 }, new { a = 35 }, new { a = 3 } };
var myInstance2 = new[] { new { b = 5 }, new { b = 20 } };
var minObject1 = myInstance1.ToList().OrderBy(elem => elem.a).FirstOrDefault();
var minObject2 = myInstance2.ToList().OrderBy(elem => elem.b).FirstOrDefault();
Console.WriteLine($"Min a instance1: {minObject1.ToString()}");
Console.WriteLine($"Min b instance2: {minObject2.ToString()}");
Console.ReadLine();
}
}
}
Output:
Once you are able to get your min, or apply the logic you wish to your enum type, you can destroy or do whatever you want to your obtained enumeration intance of your enum type.

Enum can be cast to int
EnumA valA = EnumA.a; //10
EnumB valB = EnumB.b; //5
if((int)valA < (int)valB) // 10 < 5
{ Destroy(a);}
else {Destroy(b);}
Edit:
public static int CompareAtoB(int a, int b)
{
if(a==b) return 0;
return (a < b) ? 1 : -1;
}
You can now pass any value that you cast when you give as parameter.
int result = CompareAtoB((int)someEnum, (int) otherEnum);
Then act based on result.

Related

c# use one variable value to set a second from a fixed list

I'm parsing a CSV file in a c# .net windows form app, taking each line into a class I've created, however I only need access to some of the columns AND the files being taken in are not standardized. That is to say, number of fields present could be different and the columns could appear in any column.
CSV Example 1:
Position, LOCATION, TAG, NAME, STANDARD, EFFICIENCY, IN USE,,
1, AFT-D3, P-D3101A, EQUIPMENT 1, A, 3, TRUE
2, AFT-D3, P-D3103A, EQUIPMENT 2, B, 3, FALSE
3, AFT-D3, P-D2301A, EQUIPMENT 3, A, 3, TRUE
...
CSV Example 2:
Position, TAG, STANDARD, NAME, EFFICIENCY, LOCATION, BACKUP, TESTED,,
1, P-D3101A, A, EQUIPMENT 1, 3, AFT-D3, FALSE, TRUE
2, P-D3103A, A, EQUIPMENT 2, 3, AFT-D3, TRUE, FALSE
3, P-D2301A, A, EQUIPMENT 3, 3, AFT-D3, FALSE, TRUE
...
As you can see, I will never know the format of the file I have to analyse, the only thing I know for sure is that it will always contain the few columns that I need.
My solution to this was to ask the user to enter the columns required and set as strings, the using their entry convert that to a corresponding integer that i could then use as a location.
string standardInpt = "";
string nameInpt = "";
string efficiencyInpt = "";
user would then enter a value from A to ZZ.
int standardLocation = 0;
int nameLocation = 0;
int efficiencyLocation = 0;
when the form is submitted. the ints get their final value by running through an if else... statement:
if(standard == "A")
{
standardLocation = 0;
}
else if(standard == "B")
{
standardLocation = 1;
}
...
etc running all the way to if VAR1 == ZZ and then the code is repeated for VAR2 and for VAR3 etc..
My class would partially look like:
class Equipment
{
public string Standard { get; set;}
public string Name { get; set; }
public int Efficiency { get; set; }
static Equipment FromLine(string line)
{
var data = line.split(',');
return new Equipment()
{
Standard = data[standardLocation],
Name = [nameLocation],
Efficiency = int.Parse(data[efficiencyLocation]),
};
}
}
I've got more code in there but i think this highlights where I would use the variables to set the indexes.
I'm very new to this and I'm hoping there has got to be a significantly better way to achieve this without having to write so much potentially excessive, repetitive If Else logic. I'm thinking some kind of lookup table maybe, but i cant figure out how to implement this, any pointers on where i could look?
You could make it automatic by finding the indexes of the columns in the header, and then use them to read the values from the correct place from the rest of the lines:
class EquipmentParser {
public IList<Equipment> Parse(string[] input) {
var result = new List<Equipment>();
var header = input[0].Split(',').Select(t => t.Trim().ToLower()).ToList();
var standardPosition = GetIndexOf(header, "std", "standard", "st");
var namePosition = GetIndexOf(header, "name", "nm");
var efficiencyPosition = GetIndexOf(header, "efficiency", "eff");
foreach (var s in input.Skip(1)) {
var line = s.Split(',');
result.Add(new Equipment {
Standard = line[standardPosition].Trim(),
Name = line[namePosition].Trim(),
Efficiency = int.Parse(line[efficiencyPosition])
});
}
return result;
}
private int GetIndexOf(IList<string> input, params string[] needles) {
return Array.FindIndex(input.ToArray(), needles.Contains);
}
}
You can use the reflection and attribute.
Write your samples in ,separated into DisplayName Attribute.
First call GetIndexes with the csv header string as parameter to get the mapping dictionary of class properties and csv fields.
Then call FromLine with each line and the mapping dictionary you just got.
class Equipment
{
[DisplayName("STND, STANDARD, ST")]
public string Standard { get; set; }
[DisplayName("NAME")]
public string Name { get; set; }
[DisplayName("EFFICIENCY, EFFI")]
public int Efficiency { get; set; }
// You can add any other property
public static Equipment FromLine(string line, Dictionary<PropertyInfo, int> map)
{
var data = line.Split(',').Select(t => t.Trim()).ToArray();
var ret = new Equipment();
Type type = typeof(Equipment);
foreach (PropertyInfo property in type.GetProperties())
{
int index = map[property];
property.SetValue(ret, Convert.ChangeType(data[index],
property.PropertyType));
}
return ret;
}
public static Dictionary<PropertyInfo, int> GetIndexes(string headers)
{
var headerArray = headers.Split(',').Select(t => t.Trim()).ToArray();
Type type = typeof(Equipment);
var ret = new Dictionary<PropertyInfo, int>();
foreach (PropertyInfo property in type.GetProperties())
{
var fieldNames = property.GetCustomAttribute<DisplayNameAttribute>()
.DisplayName.Split(',').Select(t => t.Trim()).ToArray();
for (int i = 0; i < headerArray.Length; ++i)
{
if (!fieldNames.Contains(headerArray[i])) continue;
ret[property] = i;
break;
}
}
return ret;
}
}
try this if helpful:
public int GetIndex(string input)
{
input = input.ToUpper();
char low = input[input.Length - 1];
char? high = input.Length == 2 ? input[0] : (char?)null;
int indexLow = low - 'A';
int? indexHigh = high.HasValue ? high.Value - 'A' : (int?)null;
return (indexHigh.HasValue ? (indexHigh.Value + 1) * 26 : 0) + indexLow;
}
You can use ASCII code for that , so no need to add if else every time
ex.
byte[] ASCIIValues = Encoding.ASCII.GetBytes(standard);
standardLocation = ASCIIValues[0]-65;

c# range lookup within a collection

I have searched through the StackOverflow yet couldn't find my question.
I have some data like this:
object a -> min:3 max:13
object b -> min:11 max:20
object c -> min:16 max:21
...
z-> min:200 max:250
For a specified interval, I expect a, b, c or other objects or a list.
For example if (6,8) is passed then I want to have "a", if (12,13) is passed I want to have a list of "a and b", if (17, 20) is passed I want to have a list of "b and c" and if (3,250) then I want to have a list of all.
I don't know in which type of collection I should store the values (3, 13, object a) and others.
Can you name the collection and give an example?
Thanks in advance...
p.s. sorry if I couldn't describe well because of my English and thank you all
So you want to find objects where the min value is smaller/equal the passed min-value and the max value is larger/equal the passed max-value.
var query = objects.Where(obj=> obj.MinVal <= minVal && obj.MaxVal >= maxVal);
Can you name the collection and give an example?
So you don't have a collection? You should fill a List<Range> where Range is a custom class with at least two properties MinVal and MaxVal.
void Main()
{
var input = new List<Interval>
{
new Interval { Name = "a", Min = 3, Max = 13 },
new Interval { Name = "b", Min = 11, Max = 20 },
new Interval { Name = "c", Min = 16, Max = 21 },
new Interval { Name = "z", Min = 200, Max = 250 }
};
var interval = new Interval { Name = "search", Min = 12, Max = 13 };
// Don't forget the third case when the interval
// you're looking for is inside your input intervals
// Min = 210, Max = 220 should return "z"
var result = input.Where(i => (interval.Min <= i.Min && i.Min <= interval.Max) ||
(interval.Min <= i.Max && i.Max <= interval.Max) ||
(i.Min <= interval.Min && interval.Max <= i.Max));
}
class Interval
{
public string Name;
public int Min;
public int Max;
}
You can either create your own type or you can use Tuple<int, int> to represent one object. Then you can create and populate a List of these objects to store your entire collection. After that you can use LINQ to query for the desired objects:
List<Tuple<int, int>> YourCollection = new List<Tuple<int, int>>();
YourCollection.Add(new Tuple<int, int>(3, 13));
YourCollection.Add(new Tuple<int, int>(11, 20));
YourCollection.Add(new Tuple<int, int>(16, 21));
var Results = YourCollection.Where(x => x.Item1 <= MAX && MIN <= x.Item2);
where MIN and MAX define the range that you're interested in. Note that the condition above looks for overlapping (intersection) as appears to be what is needed.
sing a fork of #aush code it will be bettler if you can inherint the class System.Collections.CollectionBase then you can make an easy foreach implementing this class.
structure Interval{
public string Name;
public int Min;
public int Max;
public Interval(string Name,int Min,int Max){
this.Name = Name;
this.Min = Min;
this.Max = Max;
}
public bool IsInsideOfRange(int value){
if(value >= this.Min && value <= this.Max){
return true;
}else{
return false;
}
}
public overrides ToString(){
return this.Name;
}
}
class IntervalCollection : System.Collections.CollectionBase {
public void Add(string Name,int Min,int Max){
Interval Item = new Interval(Name,Min,Max);
this.List.Add(Item);
}
public void Add(Interval Item){
this.List.Add(Item);
}
public string Encode(param int[] values){
string EcodedText = "";
foreach(int iValue in values){
foreach(Interval Item in this){
if(Item.IsInsideOfRange(iValue)){
EncodedText +=Item.ToString();
}
}
}
return EcodedText;
}
}
you can implement this class like this
IntervalCollection Intervals = new IntervalCollection();
string EncodeText = "";
Intervals.Add(new Interval { Name = "a", Min = 3, Max = 13 });
Intervals.Add(new Interval { Name = "b", Min = 11, Max = 20 });
Intervals.Add(new Interval { Name = "c", Min = 16, Max = 21 });
Intervals.Add( "z", 200, 250 }); //you can add item in this way too.
EncodeText = Intervals.Encode(6,8,12,13,17,20);

How to enumerate values and determine which is the correct scenario of a enum

I could be using enum the wrong way but this is my premise. I basically have a set of 3 strings that could come in any order. And what i'm trying to do is pick my enum that matches this order. Basically I want to know which of my scenarios applies to the string that came in.
I've been working on a test application just to pick the correct Possibility. Perhaps the code below will make more sense. The foreach loops below also might not be the best way of doing it. In the below code you can see I have { "Cow", "Chicken", "Egg" }; I want to match this to the enum Scenario2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EnumEnumerables
{
class Program
{
enum Possibilitys
{
Scenario1 = Options.Chicken + Options.Cow + Options.Egg,
Scenario2 = Options.Cow + Options.Chicken + Options.Egg,
Scenario3 = Options.Egg + Options.Cow + Options.Chicken
}
enum Options
{
Chicken,
Cow,
Egg
}
static void Main(string[] args)
{
//this should result in scenario 1
//string[] myOrderofHistory = { "Chicken", "Cow", "Egg" };
//this should result in scenario 2
string[] myOrderofHistory = { "Cow", "Chicken", "Egg" };
foreach (string history in myOrderofHistory)
{
foreach (var value in Enum.GetValues(typeof(Possibilitys)))
{
if (value == history)
{
Console.WriteLine("{0,3} 0x{0:X8} {1}",
(int)value, ((Possibilitys)value));
}
}
}
}
}
}
I would never recommend using Enums like this but by creating a [Flags] Enum and using the left shift operator << you can do this:
class Program
{
[Flags]
enum Options
{
None = 0,
Chicken = 1,
Cow = 2,
Egg = 4,
}
enum Possibilities
{
Order1 = (Options.Chicken << 4) + (Options.Cow << 2) + Options.Egg,
Order2 = (Options.Cow << 4) + (Options.Chicken << 2) + Options.Egg,
Order3 = (Options.Egg << 4) + (Options.Cow << 2) + Options.Chicken,
}
static void Main(string[] args)
{
//this should result in scenario 1
//string[] myOrderofHistory = { "Chicken", "Cow", "Egg" };
//this should result in scenario 2
string[] myOrderofHistory = { "Cow", "Chicken", "Egg" };
int[] shiftValue = new int[] { 4, 2, 0 };
int shiftIndex = 0;
int possibility = 0;
foreach (string history in myOrderofHistory)
{
Options options = (Options)Enum.Parse(typeof(Options), history);
possibility += ((int)options) << shiftValue[shiftIndex];
shiftIndex++;
}
Console.WriteLine(((Possibilities)possibility).ToString());
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}

How to get a complete row or column from 2D array in C#

I do not want to use a jagged array and I have a 2D array and I want to get a complete column or row without looping through it. Does anyone have an idea how it can be done.
double [,] array = new double [3,3] ;
1 2 3
4 5 6
Out: 1 2 3 or 2 5
To get a specific row or column from the multidimensional array you can use some LINQ:
public class CustomArray<T>
{
public T[] GetColumn(T[,] matrix, int columnNumber)
{
return Enumerable.Range(0, matrix.GetLength(0))
.Select(x => matrix[x, columnNumber])
.ToArray();
}
public T[] GetRow(T[,] matrix, int rowNumber)
{
return Enumerable.Range(0, matrix.GetLength(1))
.Select(x => matrix[rowNumber, x])
.ToArray();
}
}
You can optimise it for getting rows by using Buffer.BlockCopy(), but to get a column you'll have to loop. Buffer.BlockCopy() ultimately uses a processor instruction to copy a block of memory, so it is pretty fast.
It's convenient to put the code into an extension method to make it easier to call. Note that Buffer.BlockCopy() can only be used on arrays of primitive types, i.e. int, double, char etc. This does NOT include string.
Here's a compilable example:
using System;
using System.Linq;
using System.Runtime.InteropServices;
namespace ConsoleApplication4
{
public static class Program
{
private static void Main()
{
var array = new [,]
{
{0.1, 0.2, 0.3, 0.4, 0.5},
{1.1, 1.2, 1.3, 1.4, 1.5},
{2.1, 2.2, 2.3, 2.4, 2.5},
{3.1, 3.2, 3.3, 3.4, 3.5},
};
var row = array.GetRow(2);
// This prints 2.1, 2.2, 2.3, 2.4, 2.5
Console.WriteLine(string.Join(", ", row.Select(element => element.ToString())));
}
}
public static class ArrayExt
{
public static T[] GetRow<T>(this T[,] array, int row)
{
if (!typeof(T).IsPrimitive)
throw new InvalidOperationException("Not supported for managed types.");
if (array == null)
throw new ArgumentNullException("array");
int cols = array.GetUpperBound(1) + 1;
T[] result = new T[cols];
int size;
if (typeof(T) == typeof(bool))
size = 1;
else if (typeof(T) == typeof(char))
size = 2;
else
size = Marshal.SizeOf<T>();
Buffer.BlockCopy(array, row*cols*size, result, 0, cols*size);
return result;
}
}
}
As of March 2021, you can now use the very cool Span2D class for this!
If you are happy using spans (I highly recommend reading about them, they are awesome), you can use the following code
var span2D = new Span2D<double>(array);
//Gets the first row and returns a span of it
var rowSpan = span2D.GetRowSpan(0);
foreach(var number in rowSpan)
{
//Do something with numbers
}
//Gets the 2nd Column as a RefEnumerable and converts it to an array
var column = span2D.GetColumn(1).ToArray();
Here is how i have done it you can use
GetLength(0)
to get the columns and use
GetLength(1)
to get the rows of the 2 Dimensional array and you loop thru it with the for loop if any one else needs this.
string text = "";
for (int i = 0; i < array.GetLength(0); i++)
{
text += Convert.ToString(array[i, 2]) + "\n";
}
an alternative way you can do it is by using a List instead of an array.
Specifically in your case you'd do something like that:
Initially create an inner class that represents a tuple of the array
Create a List of the inner class
Populate the inner class
Get the row that contains something specific
Get the column that contains something specific
public static void Main(string[] args)
{
// #2 -- Instantiate List of myClass
List<myClass> myList = new List<myClass>();
//
// #3 -- Populate the list
myList.Add(new myClass(1,2,3));
myList.Add(new myClass(3,4,5));
myList.Add(new myClass(5,6,6));
//
// #4 -- Get the line where a == 1
myList.Find(x=>x.a == 1);
//
// #5 -- Get column b
myList.Select(x=>x.b);
}
// #1 -- Create the inner class
public class myClass
{
public int a;
public int b;
public int c;
public myClass(int a, int b, int c)
{
this.a =a;
this.b =b;
this.c =c;
}
}
what is needed is a jagged array (not a multidimensional array)
https://msdn.microsoft.com/en-us/library/2s05feca.aspx
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[] { 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 11, 22 };
full example with columns:
using System;
using System.Collections.Generic;
namespace Rextester
{
public class Program
{
public static T[] column<T>(T[][] jaggedArray,int wanted_column)
{
T[] columnArray = new T[jaggedArray.Length];
T[] rowArray;
for(int i=0;i<jaggedArray.Length;i++)
{
rowArray=jaggedArray[i];
if(wanted_column<rowArray.Length)
columnArray[i]=rowArray[wanted_column];
}
return columnArray;
}
public static void Main(string[] args)
{
//Your code goes here
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[] { 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 11, 22 };
Console.WriteLine("Hello, world!");
Console.WriteLine(string.Join(" ",jaggedArray[1]));
Console.WriteLine(string.Join(" ",column(jaggedArray,1)));
}
}
}
similar idea, using extensions:
using System;
using System.Collections.Generic;
namespace Rextester
{
public static class MyExtensions
{
public static string Extend(this Array array)
{
return "Yes, you can extend an array";
}
public static T[] column<T>(this T[,] multidimArray,int wanted_column)
{
int l=multidimArray.GetLength(0);
T[] columnArray = new T[l];
for(int i=0;i<l;i++)
{
columnArray[i]=multidimArray[i,wanted_column];
}
return columnArray;
}
public static T[] row<T>(this T[,] multidimArray,int wanted_row)
{
int l=multidimArray.GetLength(1);
T[] rowArray = new T[l];
for(int i=0;i<l;i++)
{
rowArray[i]=multidimArray[wanted_row,i];
}
return rowArray;
}
}
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello, world!");
int [,] multidimArray = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
Console.WriteLine(string.Join(" ",multidimArray.column(0)));
Console.WriteLine(string.Join(" ",multidimArray.row(0)));
}
}
}
My use case differs from the question, but is similar. I needed a 2D array of float[2] arrays, that I was using to represent complex numbers.
float[,,] myarray = new float[100,100,2];
float[] result = myarray[1,1]; <-- fails to compile needs all 3 coordinates
The jagged array Simmon mentioned provided the solution.
float[,][] myarray = new float[100,100][];
...
myarray[x,y] = new float[2]; <-- Initialise all elements of jagged 2D array in loop
...
float[] result = [100,100];
if you know the index of the numbers to output..then you don't need to use a loop to get the output desired...
double[,] array = new double[3,3] {{1,2,3}, {4,5,6}, {7,8,9}};
int firstNum = array[0,1];
int secondNum = array[1,1];
this will get 2, 5

Reduce list of enum values to single int

I have an enum which designates categories (columns) for some data. I would like to be able to store a sorting order, so a list of these enums as a single int value. So that no matter what the size of the list (within reason) there is a unique int that can reconstruct the list.
public enum SortingCategories
{
ORDER_DATE = 1,
CUSTOMER_STATE = 2,
CUSTOMER_NAME = 3,
CUSTOMER_HAIRCOLOR = 4,
...
}
public IEnumerable<SortingCategories> GetSortingOrder(int code)
{
...
}
public int GetSortingCode(IEnumerable<SortingCategories> order)
{
...
}
public const List<SortingCategories> PossibleSortingOrder = new List<SortingCategories>()
{
SortingCategories.CUSTOMER_NAME,
SortingCategories.CUSTOMER_STATE,
SortingCategories.ORDER_DATE,
SortingCategories.CUSTOMER_HAIRCOLOR
};
public const List<SortingCategories> AnotherPossibleSortingOrder = new List<SortingCategories>()
{
SortingCategories.CUSTOMER_STATE,
SortingCategories.CUSTOMER_HAIRCOLOR
};
How about just concatenating the values if they are < 10
Eg.
1324
2341
4231
Traditionally, the solution is to use binary flags for this purpose. This lets you save the options, but not the order. There is no way to save the selections AND there order in a single number unless you create flags for every legal combination. You could however, construct your own custom string format for such a list. i.e) {3}{6}{1} and cast those values as SortingCategories before doing the sort.
Here is how the flags option might look.
public enum SortingCategories
{
ORDER_DATE = 0x1,
CUSTOMER_STATE = 0x2,
CUSTOMER_NAME = 0x4,
CUSTOMER_HAIRCOLOR = 0x8,
...
}
Then use binary operators. i.e)
uint categories = SortingCategories.ORDER_DATE | SortingCategories.CUSTOMER_NAME;
if((categories & SortingCategories.ORDER_DATE) == SortingCategories.ORDER_DATE)
do something...
Assuming you've set the enum up where each value is a unique power of 2, like this:
[Flags]
public enum SortingCategories
{
ORDER_DATE = 1,
CUSTOMER_STATE = 2,
CUSTOMER_NAME = 4,
CUSTOMER_HAIRCOLOR = 8,
}
You can use the Aggregate extension method:
var myEnumList = new List<SortingCategories>()
{
SortingCategories.CUSTOMER_NAME,
SortingCategories.CUSTOMER_STATE,
SortingCategories.ORDER_DATE,
SortingCategories.CUSTOMER_HAIRCOLOR
};
var myEnumValue = myEnumList.Aggregate((x, y) => x | y);
Update this is a generalization from Rob van der Veer's answer which will work for enum types with up to 9 members—or more generally for enum types with n members it can encode lists up to logn(231-1) items. It will ensure you can decode the integer to get the original list, including the order in which the items appeared in the list:
// Get the number of members in the enum type
// Note, you could hard code this as a private const as well
int numberOfMembers = Enum.GetValues(typeof(SortingCategories)).Length;
// Get integer value from enum list
int EnumListToInt(IEnumerable<SortingCategories> list, int numberOfMembers)
{
return list.Aggregate(
new { i = 0, p = 1 },
(a, e) => new { i = (a.i + (int)e * a.p), p = a.p * numberOfMembers },
a => a.i);
}
// Get integer value representing list
List<SortingCategories> EnumListToInt(int intVal, int numberOfMembers)
{
return Enumerable.Range(1, numberOfMembers).Select(
p => {
var result = intValue % numberOfMembers;
intValue /= numberOfMembers;
return (SortingCategories)result;
}).ToList();
}
Note that unlike the previous method, this method assumes the enum values range from 0 to N, as though you didn't specify any explicit values for the enum members. This could be modified to support any values by using something along the lines of:
int numberOfMembers = Enum.GetValues(typeof(SortingCategories)).Cast<int>().Max() + 1;

Categories