Order IEnumerable without LINQ - c#

Can you advice any solution of how to sort IEnumerable<byte> indexes in .NET 3.0 (no LINQ)?
Of course it is possible to determine indexes length, create array, copy element-by-element, then call Array.Sort(array). But may be can you suggest anything else?

As long as you aren't using the 2.0 compiler (so: VS 2008 / 2010 / 2012), you can use LINQBridge, and use LINQ-to-Objects from your .NET 2.0/3.0 code.
The other lazy solution is:
List<byte> list = new List<byte>(indexes);
list.Sort();
// list is now a sorted clone of the data

Don't think there is any other solution then iterating over "manually", in C# 2.0
Another option of creating array.
You can create a List<>
var list = new List<byte>(indexes );
list.Sort(delegate(byte b1, byte b2)
{
//your comparison logic here
});
It's more compact then simple for or foreach iteration over collection.

The entire IEnumerable<> has to be read when you sort it, so there is no way around that. Even the Linq to Objects method Sort keeps the entire collection in memory.
Create a List<byte> from the IEnumerable<byte> and sort it:
List<byte> list = new List<byte>(indexes);
list.Sort();

Since you can't really change an IEnumerable, you're going to have to copy the data somewhere else to sort it.
However, note you're sorting bytes, you can use Bucket Sort for ultra-efficient sorting.

http://www.codeproject.com/Articles/80546/Comparison-Sorting-Algorithms-in-C-Explained
This came in handy when i was on a search for a solution

Related

Remove elements from one Hashset where NOT in another Hashset?

I am aware of hashsetA.Except(hashsetB) to remove elements from hashsetA that exist in hashsetB. However, I want to remove elements from hashsetA that don't exist in hashsetB.
Currently I just copy hashsetA to a new Hashset then use ExceptWith() twice:
hashsetC = new HashSet<var>(hashsetA);
hashsetC.ExceptWith(hashsetB);
hashsetA.ExceptWith(hashsetC);
The performance of this is plenty good enough for my purposes, but I was wondering if there's a built in method to make this faster/more concise?
Or am I missing an obvious way to select from the sets?
Simply use IntersectWith method.
hashsetA.IntersectWith(hashsetB);
res = hashsetA.Where(p=> hashsetB.Contains(p)).
Given that lookup in a Hashset is O(1), that should sum to O(n).

How to Jagged List C#

I am trying to create a jagged array but due to the dynamic-ness of the data I am working with I do not want to waste resources creating a a large jagged array.
I am currently doing:
int[][][] data = new data[Int16.MaxValue][][];
I do not how big the data set is, or is there a better way than doing it via Lists?
Yes, you should use List<T>.
In this case, you would use List<List<List<int>>>.
Your array:
int[][][] data = new data[Int16.MaxValue][Int16.MaxValue][Int16.MaxValue];
will take up (2^16)^3 = 2^48 = way more storage space than you have,
not to mention that that declaration is not valid C#.
If you don't know how much space you need when you initialize, then it would be best to use a dynamically resizing list.
Use a variable similar to this:
List<List<List<int>>> data = new List<List<List<int>>>();
This variable allows you to add List<List<int>>'s to it, and those lists contain List<int>'s, which of course contain int's
If you absolutely do not want to use Lists, you can always replicate what Lists do under the hood: Create your array with a small number of elements, and when you reach the maximum, create a new array that is double the original's size, copy your existing array into it, and dispose of your original. Continue this pattern until you are done. I recommend using Lists instead, but this is how you would get around it if, for some reason, you just don't want to use Lists.
In fact, you can create jagged arrays without defining second and further dimensions.
int[][][] jagged = new int[256][][];
But at large datasets it is more effective to use streaming data - i.e., combinations of IEnumerable<T>.

C# linked lists

very basic question, but is there any ToArray-like function for c# linked lists that would return an array of only part of the elements in the linkedlist.
e.g.: let's say my list has 50 items and I need an array of only the first 20. I really want to avoid for loops.
Thanks,
PM
Use Linq?
myLinkedList.Take(20).ToArray()
or
myLinkedList.Skip(5).Take(20).ToArray()
You say you "really want to avoid for loops" - why?
If you're using .NET 3.5 (or have LINQBridge), it's really easy:
var array = list.Take(20).ToArray();
... but obviously that will have to loop internally.
Note that this will create a smaller array if the original linked list has fewer than 20 elements. It's unclear whether or not that's what you want.
Something is going to have to loop internally, sooner or later - it's not like there's going to be a dedicated CPU instruction for "navigate this linked list and copy a fixed number of pointers into a new array". So the question is really whether you do it or a library method.
If you can't use LINQ, it's pretty easy to write the equivalent code yourself:
int size = Math.Min(list.Count, 20);
MyType[] array = new MyType[size];
var node = list.First;
for (int i = 0; i < size; i++)
{
array[i] = node.Value;
node = node.Next;
}
That will actually be slightly more efficient than the LINQ approach, too, because it creates the array to be exactly the right size to start with. Yes, it uses a loop - but as I say, something's got to.
If you're using the LinkedList collection class (from System.Collections.Generic), you can use LINQ to get it:
var myArray = list.Take(20).ToArray();

How to store related data

In my program (a program that assists with pathfinding), i need to store a list that contains entries consisting of a start node and an end node. A dictionary won't work as i cannot guarantee that the "key" (a node of course) will be unique. What is the best way to store this manner of data?
Edit: i use C# and .Net 3.5.
You might be better off simply using an array of structs. Or a vector of structs. This allows for non-unique nodes in your list. Vectors are a standard template in C++, but if C# doesn't support it, then an array should work fine.
Would it be possible for you to use a List of KeyValuePair objects? Like this?
List<KeyValuePair<ObjectA, ObjectB>> list = new List<KeyValuePair<ObjectA, ObjectB>>();
I don't have VS in front of me right now, so I'm not sure if I have the syntax 100% right, but hopefully this helps.
If your language of choice supports sets, a set of (start, end) tuples is what you might be looking for.

Array of an unknown length in C#

I've just started learning C# and in the introduction to arrays they showed how to establish a variable as an array but is seems that one must specify the length of the array at assignment, so what if I don't know the length of the array?
Arrays must be assigned a length. To allow for any number of elements, use the List class.
For example:
List<int> myInts = new List<int>();
myInts.Add(5);
myInts.Add(10);
myInts.Add(11);
myInts.Count // = 3
Use List<> to build up an 'array' of unknown length.
Use List<>.ToArray() to return a real array, and not a List.
var list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
var array = list.ToArray();
A little background information:
As said, if you want to have a dynamic collection of things, use a List<T>. Internally, a List uses an array for storage too. That array has a fixed size just like any other array. Once an array is declared as having a size, it doesn't change. When you add an item to a List, it's added to the array. Initially, the List starts out with an array that I believe has a length of 16. When you try to add the 17th item to the List, what happens is that a new array is allocated, that's (I think) twice the size of the old one, so 32 items. Then the content of the old array is copied into the new array. So while a List may appear dynamic to the outside observer, internally it has to comply to the rules as well.
And as you might have guessed, the copying and allocation of the arrays isn't free so one should aim to have as few of those as possible and to do that you can specify (in the constructor of List) an initial size of the array, which in a perfect scenario is just big enough to hold everything you want. However, this is micro-optimization and it's unlikely it will ever matter to you, but it's always nice to know what you're actually doing.
You can create an array with the size set to a variable, i.e.
int size = 50;
string[] words = new string[size]; // contains 50 strings
However, that size can't change later on, if you decide you need 100 words. If you need the size to be really dynamic, you'll need to use a different sort of data structure. Try List.
Use an ArrayList if in .NET 1.x, or a List<yourtype> if in .NET 2.0 or 3.x.
Search for them in System.Collections and System.Collections.Generics.
You might also want to look into Dictionarys if your data is unique, This will give you two columns to work with.
User name , Total bill
it gives you a lot of built in tools to search and update just the value.
var yummy = new List<string>();
while(person.FeelsHappy()) {
yummy.Add(person.GetNewFavoriteFood());
}
Console.WriteLine("Sweet! I have a list of size {0}.", list.Count);
Console.WriteLine("I didn't even need to know how big to make it " +
"until I finished making it!");
try a generic list instead of array
In a nutshell, please use Collections and Generics.
It's a must for any C# developer, it's worth spending time to learn :)
As detailed above, the generic List<> is the best way of doing it.
If you're stuck in .NET 1.*, then you will have to use the ArrayList class instead. This does not have compile-time type checking and you also have to add casting - messy.
Successive versions have also implemented various variations - including thread safe variants.
If you really need to use an array instead of a list, then you can create an array whose size is calculated at run time like so...
e.g i want a two dimensional array of size n by n. n will be gotten at run time from the user
int n = 0;
bool isInteger = int.TryParse(Console.ReadLine(), out n);
var x = new int[n,n];

Categories

Resources