I am trying to select different type of Enum Values when comparing, based on what user selected.
This is my code:
public enum CategoryType { E1, E2, E3, E4 }
List1.Add(new model{ Line = "Line 1", Category = model.CategoryType.E3| model.CategoryType.E1});
List1.Add(new model{ Line = "Line 2", Category = model.CategoryType.E2 | model.CategoryType.E1});
List1.Add(new model{ Line = "Line 3", Category = model.CategoryType.E4 | model.CategoryType.E3});
var modelEnum = CategoryType.E1 | CategoryType.E3
var ValidLines = List1.Where(P => P.Category == modeEnum ).ToList()
.Select(P => P.Line).ToList();
The above code does not work. Since I am looking for E1 or E3, it should return ANY items that contains E1 or E3. In this case, it should return all 3 items above because all of them contains either E1 or E3.
What am I doing wrong?
Thanks
You seem to be a bit confused. I believe what you want is to use the Flags attribute on your enum then assign unique values to them (it's difficult cause your code is invalid). For example:
[Flags]
public enum CategoryType { E1 = 1, E2 = 2, E3 = 4, E4 = 8 }
In this way your 'bit or' operator (|) will allow you to properly combine your values (up to 31 values, plus 0) into a unique value. To test it you want to do something like this:
if ((value & CategoryType.E2) == CategoryType.E2) { ...
They way you have it your bit or's will return non-unique ints. What you have is this:
public enum CategoryType { E1 = 0, E2 = 1, E3 = 2, E4 = 3 }
This is the default enum behavior. So E1 | E3 is 0 | 2 which is 2. E2 | E3 is 1 | 2 which is 3, which is the same as E4.
Related
I have the need to create scheduled windows tasks using a C# app. I have a comma separated string that stores the months I'd like to run the task on. The string contains the short values for the type MonthsOfYear - eg. "1,2,4,16,128,1024".
The example I have shows that you can assign multiple months seperated by a pipe as follows:
MonthlyTrigger mt = new MonthlyTrigger();
mt.StartBoundary = Convert.ToDateTime(task.getStartDateTime());
mt.DaysOfMonth = new int[] { 10, 20 };
mt.MonthsOfYear = MonthsOfTheYear.July | MonthsOfTheYear.November;
My question is, how do I assign multiple months to the trigger dynamically, using the values from the comma seperated string.
I'm not quite sure, what your problem is. And you didn't post code of your Trigger or your enum. Because of this i'll provide a complete example with a List for comparesion:
public class MonthlyTrigger
{
[Flags] // Important because we want to set multiple values to this type
public enum MonthOfYear
{
Jan = 1, // 1st bit
Feb = 2, // 2nd bit..
Mar = 4,
Apr = 8,
May = 16,
Jun = 32,
Jul = 64,
Aug = 128,
Sep = 256,
Oct = 512,
Nov = 1024,
Dec = 2048
}
public HashSet<int> Months { get; set; } = new HashSet<int>(); // classical list to check months
public MonthOfYear MonthFlag { get; set; } // out new type
}
public static void Main(string[] args)
{
MonthlyTrigger mt = new MonthlyTrigger();
string monthsFromFileOrSomething = "1,3,5,7,9,11"; // fake some string..
IEnumerable<int> splittedMonths = monthsFromFileOrSomething.Split(',').Select(s => Convert.ToInt32(s)); // split to values and convert to integers
foreach (int month in splittedMonths)
{
mt.Months.Add(month); // adding to list (hashset)
// Here we "add" another month to our Month-Flag => "Flag = Flag | Month"
MonthlyTrigger.MonthOfYear m = (MonthlyTrigger.MonthOfYear)Convert.ToInt32(Math.Pow(2, month - 1));
mt.MonthFlag |= m;
}
Console.WriteLine(String.Join(", ", mt.Months)); // let's see our list
Console.WriteLine(mt.MonthFlag); // what is contained in our flag?
Console.WriteLine(Convert.ToString((int)mt.MonthFlag, 2)); // how is it binarily-stored?
// Or if you like it in one row:
mt.MonthFlag = 0;
foreach (MonthlyTrigger.MonthOfYear m in monthsFromFileOrSomething.Split(',').Select(s => (MonthlyTrigger.MonthOfYear)Convert.ToInt32(s)))
mt.MonthFlag = m;
return;
}
Adding or removing single Flags in an enum:
MyEnumType myEnum = 1; // enum with first flag set
myEnum |= 2; // Adding the second bit. Ofcouse you can use the enum-name here "MyEnumType.MyValueForBitTwo"
// Becuase:
// 0000 0001
// | 0000 0010 "or"
// = 0000 0011
myEnum &= (int.MaxValue - 2) // Deletes the second enum-bit.
// Because:
// 0000 0011
// & 1111 1101 "and"
// = 0000 0001
I have a following set of numbers:
1 137
1 143
11 37
11 46
11 132
46 65
46 139
69 90
Now, I need to group the data by the first value in a way that no group key is present in the group values. So, for instance, if I were to simply group data, I'd get this result:
1 137
143
11 37
46
132
46 65
139
69 90
46 here is a group key in the third group and a group value in the second group. In this case I need to merge the group values of the third group into a second group and remove the third group.
The end result of the grouping should look like this:
1 137
143
11 37
46
132
65
139
69 90
I'm relatively new to C#, so I was wondering if there's a fancy way to do it using LINQ.
Try this LINQ solution:
var numbers = new List<Number>
{
new Number {X = 1, Y = 137},
new Number {X = 1, Y = 143},
new Number {X = 11, Y = 37},
new Number {X = 11, Y = 46},
new Number {X = 11, Y = 132},
new Number {X = 46, Y = 65},
new Number {X = 46, Y = 139},
new Number {X = 69, Y = 90}
};
var result = numbers.GroupBy(c => c.X);
var result2 = numbers.FirstOrDefault(c => result.Select(d => d.Key).Contains(c.Y));
var finalResult = numbers.Where(x => x.X == result2?.Y)
.Select(x => { x.X = result2.X;x.Y = x.Y; return x; } )
.Union(numbers.Where(c => c.X != result2?.Y)).GroupBy(c => c.X ,
(key, element) => new
{
Key = key,
Element = element.Select(c => c.Y).ToList()
});
The result:
This could work for you
public static List<Numbers> setNumbers()
{
List<Numbers> num = new List<Numbers>();
num.Add(new Numbers() { Column1 = 1, Column2 = 137 });
num.Add(new Numbers() { Column1 = 1, Column2 = 143 });
num.Add(new Numbers() { Column1 = 11, Column2 = 37 });
num.Add(new Numbers() { Column1 = 11, Column2 = 46 });
num.Add(new Numbers() { Column1 = 11, Column2 = 132 });
num.Add(new Numbers() { Column1 = 46, Column2 = 65 });
num.Add(new Numbers() { Column1 = 46, Column2 = 139 });
num.Add(new Numbers() { Column1 = 69, Column2 = 90 });
return num;
}
public static void group()
{
List<Numbers> numbers = setNumbers();
var grouppedNumbers = numbers
.GroupBy(x => x.Column1).ToList();
grouppedNumbers.AddRange(grouppedNumbers.FirstOrDefault(x => x.First().Column1.Equals(46)).Select(s => new Numbers() { Column1 = 11, Column2 = s.Column2 }).GroupBy(g => g.Column1).ToList());
grouppedNumbers.Remove(grouppedNumbers.FirstOrDefault(x => x.First().Column1.Equals(46)));
foreach (var groups in grouppedNumbers)
{
Console.WriteLine(groups.First().Column1);
foreach(var i in groups)
{
Console.WriteLine(i.Column1+" "+ i.Column2);
}
}
}
I was collect data an array with 2 coloumn look like this
---------------
Order | Value
---------------
order1 | 45
order2 | 70
order1 | 85
order2 | 32
--------------
How to get all value in the array based conditional where order= order1 only and sum them?
Thank you,
Using Linq (Where for Conditional) and (Sum for Aggregate Functions):
var sum = array.Where(x=> x.Order == "order1").Sum(x=> x.Value);
If you really meant a 2-D (Multidimentional) Array, then you can do this:
object[,] array =
{
{ "order1", 45 }, { "order2", 70 },
{ "order1", 85 }, { "order2", 32 }
};
decimal Sum = 0;
for(int i = 0; i < array.GetLength(0); i++)
{
if (array.GetValue(i, 0)?.ToString() == "order1")
{
decimal val;
if(decimal.TryParse(array.GetValue(i, 1)?.ToString(), out val))
Sum += val;
}
}
Given
(1) A database table, stored as a list of lists. The size of the table in terms of rows and columns is undefined.
List<List<string>> table = new List<List<string>>();
For example:
table.Add(new List<string>() { "a1", "b1", "c1", "d1", "e1" });
table.Add(new List<string>() { "a2", "b2", "c2", "d2", "e2" });
table.Add(new List<string>() { "a3", "b3", "c3", "d3", "e3" });
| a1 | b1 | c1 | d1 | e1 |
| a2 | b2 | c2 | d2 | e2 |
| a3 | b3 | c3 | d3 | e3 |
(2) A list of integers. These integers resemble the indexes of database columns (zero-based), e.g.:
List<int> indexes = new List<int>() { 1, 3, 4 };
Problem
My aim is to project those columns from table of which the indexes occur in the list indexes. Given the above examples, the result should be:
| b1 | d1 | e1 |
| b2 | d2 | e2 |
| b3 | d3 | e3 |
Current Solution
The best I could come up with is to iterate over all rows, like this:
List<List<string>> subtable = new List<List<string>>();
for (int index = 0; index < table.Count; index++)
{
subtable.Add(table[index].Where((t, i) => indexes.Contains(i)).ToList());
}
Request
A more elegant solution, if possible.
What about this:
List<List<string>> subtable =
table.Select(row => indexes.Select(i => row[i]).ToList()).ToList();
In case you need to check the array bounds, you can do this:
List<List<string>> subtable =
table.Select(row => indexes.Where(i => i >= 0 && i < row.Count)
.Select(i => row[i]).ToList()).ToList();
Or if you prefer query syntax:
List<List<string>> subtable =
(from row in table
select
(from i in indexes
where i >= 0 && i < row.Count
select row[i]
).ToList()
).ToList();
Select all the rows, then for each row filter out the columns that are not in your index list:
var subtable = table
.Select(row => row.Where((value, colIndex) => indexes.Contains(colIndex)))
.ToList();
If you want just to print, it is simpler (and more efficient ) to do it without queries like this:
List<List<string>> table = new List<List<string>>();
table.Add(new List<string>() { "a1", "b1", "c1", "d1", "e1" });
table.Add(new List<string>() { "a2", "b2", "c2", "d2", "e2" });
table.Add(new List<string>() { "a3", "b3", "c3", "d3", "e3" });
List<int> indexes = new List<int>() { 1, 3, 4 };
for (int index = 0; index < table.Count; index++)
{
foreach (var columnIndex in indexes)
Console.Write(table[index][columnIndex] +" ");
Console.WriteLine();
}
Console.ReadLine();
I'm familiar with t-sql but not in LINQ, I had tried basic linq but not sure on this one.
Im not sure if there's an exact equivalent in linq on my written sql statement below.
Basically I want to transfer the linq result to my domain model.
The sql query are using the same view (1 sql view)
Domain Model
Public class Result
{
Public int Key{get;set;}
Public string Name{get;set;}
}
SQL Query
SELECT DISTINCT Name = Field1 ,ItemKey = Field2 FROM sql_view
UNION
SELECT DISTINCT Name = Field3 ,ItemKey = Field4 FROM sql_view
UNION
SELECT DISTINCT Name = Field5 ,ItemKey = Field6 FROM sql_view
UNION
SELECT Name = Field7 ,ItemKey = Field8 FROM sql_view
Sample Data of sql_vw
Field1 Field2 Field3 Field4 Field5 Field6 Field7 Field8
1 A1 23 FF23 322 ZZ322 10 A10
1 A1 23 FF23 322 ZZ322 21 R21
1 A1 23 FF23 322 ZZ322 31 E31
2 B2 22 PP22 331 WW331 3 A3
2 B2 22 PP22 331 WW331 7 R7
2 B2 22 PP22 331 WW331 9 E9
2 B2 22 PP22 331 WW331 12 E12
3 C3 26 HH26 340 NN340 43 H43
3 C3 26 HH26 340 NN340 39 J39
(from v in context.View
group v by new {v.Field1, v.Field2} into g
select new Result{Key = g.Key.Field1, Item = g.Key.Field2})
.Union()//more of this may be
Updated with grouping
To makes things easier to read and understand, I would do something like that
var part1 = context.View.Select(m => new {Name = m.Field1, ItemKey = m.Field2});
var part2 = context.View.Select(m => new {Name = m.Field3, ItemKey = m.Field4});
var part3 = context.View.Select(m => new {Name = m.Field5, ItemKey = m.Field6});
var part4 = context.View.Select(m => new {Name = m.Field7, ItemKey = m.Field8});
var result = (part1.Union(part2).Union(part3).Union(part4)).Distinct();