What would be the efficient way of sorting typeof(EnumType) alphabetically?
The enum values have index non-sequential however sorted in alphabetic order.
(i.e. apple = 5, banana = 2, cantaloupe = 3)
Instantiating temporarily is fine.
Eventually I need the index code for the specific enum value selected.
I am asking because the method I came up with does not look the best:
Array tmp = Enum.GetValues(typeof(EnumType));
string[] myenum = tmp.OfType<object>().Select(o => o.ToString()).ToArray();
Array.Sort(myenum);
int enum_code = (int)Enum.Parse(typeof(EnumType), myenum.GetValue((int)selected_index).ToString());
string final_code = enum_code.ToString());
You could use Linq to write more compact and maintainable code. Unless you're doing this in the inner loop of a high-performance application, I doubt the speed of Linq vs. your original code vs. any other possible implementation will matter at all:
var sorted = (from e in Enum.GetValues(typeof(EnumType)).Cast<EnumType>()
orderby e.ToString() select e).ToList();
Given the error, a more labourious (and .net 2 compatible) solution is;
SortedDictionary<string, MyEnumType> list = new SortedDictionary<string, MyEnumType>();
foreach (Enum e in Enum.GetValues(typeof(MyEnumType)))
{
list.Add(e.ToString(), (MyEnumType)e);
}
To retrieve the enum;
MyEnumType temp = list["SomeValue"];
Related
I got a database with members, each member has a list of sports they do.
now I want to loop through a listbox and add every selected item to my database.
This is my database :
And this is my code :
foreach (var item in sportCheckedListBox.CheckedIndices)
{
int sportindex = Convert.ToInt32(item.ToString()) + 1;
var queryResult = from sp in context.Sports
where sp.sportnr == sportindex
select sp;
foreach (var sport in queryResult)
{
myMember.Sports.Add(sport);
}
}
This looks kinda 'shady', how could I do this better ?
One thing I'd do for sure is move the query out of the loop. Queries should never exist in loops for performance and maintainability reasons. LINQ knows how to translate a (new int[] { 0, 1, 2, ... }).Contains(column) construct into a WHERE column IN (0, 1, 2, ...) statement, so let's use that:
// Get all checked items together
var lookupIndices = sportCheckedListBox.CheckedIndices.Select(i => Convert.ToInt32(item.ToString()) + 1);
// Find all matching sport numbers
var queryResult = from sp in context.Sports
where lookupIndices.Contains(sp.sportnr)
select sp;
// Now loop over the results
foreach (var sport in queryResult)
{
myMember.Sports.Add(sport);
}
// save changes
I think you can just do AddRange:
myMember.Sports.AddRange(queryResult);
myMember.Sports.SaveChanges()
You may need to covert queryResult to an IEnumerable type if it's not already though.
There is nothing fundamentally wrong with your approach, but you can achieve it more concisely with Linq.
Instead of your foreach loop, if you always want to assign a new list you could use
myMember.Sports = queryResult.ToList();
If you want to instead concatenate results to an existing list, you could use
myMember.Sports = myMember.Sports.Concat(queryResult.ToList());
If you wanted to do the same as above, but not have any duplicates (as defined by the object you are adding), instead
myMember.Sports = myMember.Sports.Union(queryResult.ToList());
I have the following data set and would like to store the three arrays in one variable for lookup.
name date size
aaa 201201 0.82
bbb 201306 1.04
ccc 201209 0.91
................
How do I store all the information in one variable? There are hundreds of rows. I am working with C#. I need to be able to search through the variable. For example, if time = 201201, name = aaa, then the size is 0.82.
Best way? Create a wrapper class, store in a List, query using Linq to objects:
public class YourStuff{
public string Name;
public DateTime Date;
public double Size;
}
...
List<Stuff> myStuff = new List<Stuff>();
//then load from DataSet, DataTable, etc.
Some Linq examples:
var greaterThanOne = myStuff.Where(stuff => stuff.Size > 1);
var greaterThanOneCount = myStuff.Count(stuff => stuff.Size > 1);
var sumOfAllSizes = myStuff.Sum(stuff => stuff.Size);
With Linq to objects you can find, sort, slice and dice, group by, you name it.
EDIT: I modified my original answer to be able to search by name and date and get size.
You could use the Tuple class like this:
Dictionary<Tuple<string, DateTime>, float> dict = new Dictionary<Tuple<string, DateTime>, float>();
dict[new Tuple<string, DateTime>("aaa", DateTime.Now)] = 0.82f;
This approach assumes that the combination of name and date is unique, like an index. You can easily search by index, then.
If you need to search name/date by size, though, the wrapper class approach Adrian Carneiro suggested is probably better.
I have a class in my Windows application like so:
public class Pets
{
String Name {get;set;}
int Amount {get;set;}
}
In one of my other classes i made a List of that class like so.
List<Pets> myPets = new List<Pets>();
myPets.Add(new Pets{ Name = "Fish", Amount = 8});
myPets.Add(new Pets{ Name = "Dogs", Amount = 2});
myPets.Add(new Pets{ Name = "Cats", Amount = 2});
Is there a way i can get the Index of the Pets whos Name = "Fish"?
I realize i can do this
int pos = 0;
for(int x = 0; x<myPets.Count;x++)
{
if( myPets[x].Name == "Fish")
{
pos = x;
}
}
But in the case that i have ALOT of items in myPets it would take long to loop through them to find the one i am looking for. Is there another way to complete the task above. That would make my application run quicker? In the case that myPets has a lot of items in it.
The way you have your data structured at the moment does not lend itself well to searching by pet's name if the list is large.
So iterating manually like you suggest and what FindIndex is doing is known as a linear search which is a brute force algorithm. If you have N items in your collection, the worst case scenario to find an item is N iterations. This is known as O(N) using the Big O Notation. The speed of search grows linearly with the number of items within your collection.
For faster searching you need to change to a different data structure (like a Hashtable), use a database or implement a different search algorithm, such as a binary search( O(log(n)) complexity ).
Have a look at this question for an example:
Can LINQ use binary search when the collection is ordered?
If you want to find index only to access item of List you can use Dictionary instead.
var pets = new Dictionary<string, int>();
pets.Add("Dogs", 2);
pets.Add("Fish", 8);
int amount = pets["Fish"];
I have List which I would like to sort by many columns. For example, string[] has 5 elements (5 columns) and List has 10 elements (10 rows). For example I would like to start sorting by 1st column, then by 3rd and then by 4th.
How could it be done in the easiest way with C#?
I thought about such algorithm:
Delete values corresponding to those columns that I don't want to use for sorting
Find for each of columns that are left, the longest string that can be used to store their value
Change each row to string, where each cell occupies as many characters as there is maximum number of characters for the value for the given column
Assign int with index for each of those string values
Sort these string values
Sort the real data, with help of already sorted indices
But I think this algorithm is very bad. Could you suggest me any better way, if possible, that uses already existing features of C# and .NET?
List<string[]> list = .....
var newList = list.OrderBy(x => x[1]).ThenBy(x => x[3]).ThenBy(x => x[4]).ToList();
Something like this:
var rows = new List<string[]>();
var sortColumnIndex = 2;
rows.Sort((a, b) => return a[sortColumnIndex].CompareTo(b[sortColumnIndex]));
This will perform an in-place sort -- that is, it will sort the contents of the list.
Sorting on multiple columns is possible, but requires more logic in your comparer delegate.
If you're happy to create another collection, you can use the Linq approach given in another answer.
EDIT here's the multi-column, in-place sorting example:
var rows = new List<string[]>();
var sortColumnIndices = new[] { 1, 3, 4 };
rows.Sort((a, b) => {
for (var index in sortColumnIndices)
{
var result = a[index].CompareTo(b[index]);
if (result != 0)
return result;
}
return 0;
});
How can I sort same value fields in generic lists with a descending order.
Example:
List<int> objList = new List<int>();
objList.Add(1);
-> objList.Add(0);
-> objList.Add(0);
objList.Add(2);
-> objList.Add(0);
It's my source somehow and I want to sort for example zero values in descending mode.
I use this code for sorting the numbers (actually the depths), and above example is not related to this but somehow it's same. In my generic list I have several depths which they might be same to each other and I want to order the same fields descending.
Objects.Sort(
delegate(Classes.Object.GameObject Object1, Classes.Object.GameObject Object2)
{
return Object1.Depth.CompareTo(Object2.Depth);
}
);
Answer: Might help someone in the future
// Reverse same oredered
CurrentSameOrderedFind = Objects[0].Depth;
CurrentSameOrderedID = 0;
for (int i = 1; i <= Objects.Count - 1; i++)
{
if (Objects[i].Depth != CurrentSameOrderedFind)
{
SameOrederedFound = true;
Objects.Reverse(CurrentSameOrderedID, i - 1);
CurrentSameOrderedFind = Objects[i].Depth;
CurrentSameOrderedID = i;
}
}
if (!SameOrederedFound)
{
Objects.Reverse();
}
To sort a List<int>, which your code above shows, in descending order, there's a very simple Linq solution: objList = objList.OrderByDescending(i => i).ToList();
From reading the rest of your question, do you want to sort a list of objects with a depth property? If so, this should work for you:
var myList = new List<someTypeWithDepth>();
myList = myList.OrderByDescending(o => o.depth).ToList();
If in whatever situation you're using these Lists you can get away with typing them as IEnumerable<T> instead of List<T> then you could remove those ugly ToList() calls
If I understand you correctly, you want your list sorted in descending order based on GameObject.Depth, and you've got an implementation that sorts your collection, but in ascending order rather than descending. Given that, here's the laziest answer I could come up with:
Code edited per my comment. Really, why couldn't you have said what you wanted in the question? I agree that it isn't complicated, but you won't get good help if you don't ask good questions.
List<GameObject> oldList = new List<GameObject>(Objects);
Objects.Sort(
delegate(Classes.Object.GameObject Object1, Classes.Object.GameObject Object2)
{
int compareValue = -1 * Object1.Depth.CompareTo(Object2.Depth);
if(compareValue == 0)
compareValue = oldList.IndexOf(Object2).CompareTo(oldList.IndexOf(Object1));
return compareValue;
}
);
Hardly optimal, but it's not meant to be.