I have inserted values into Stack in C# . I need values of mystack[0], mystack[1]. How to do it. I have tried methods in stack but please give me hint of code i will try it
You can use ElementAt() for this.
Stack<Int32> foo = new Stack<Int32>();
foo.Push(5); //element 1
foo.Push(1); //element 0
int val = foo.ElementAt(1); //This is 5
Since stacks are last on first out, if you want to get the first item you added to the stack, you can use:
int val = foo.ElementAt(foo.Count - 1);
Keep in mind, ElementAt is a LINQ extension method that will enumerate the stack as an array and return the desired index. For large stacks, or where performance is critical, you might want to consider using another data structure such as List<T>.
If you need the items by index, perhaps a List<T> would be a more appropriate data structure?
A stack is intended to only allow you to get the most recently inserted item. There are ways to bypass that behavior, but surely if you need the items by index this works better:
var myList = new List<Int32>();
myList.Add(100);
myList.Add(200);
myList.Add(300);
myList.Add(400);
Console.Out.WriteLine(myList[2]); // Prints "300"
Related
Trying to create a type of low pass filter where I constantly average the previous 10 float values. Not sure whether to use builtin arrays (native .NET arrays), the .NET Stack operator, or perhaps an ArrayList or List.
In pseudocode I need to
1- Define the array or Stack containing 10 floats
2- Every update Push a new value to the Array, Stack, List
3- Check the length and if greater than10 remove the first or oldest float value from the Array, Stack, List
4- Get the average of all float values in the Array, Stack, List
5- Repeat steps 2-4
1st question Should I be using built in Arrays, Stack, ArrayList or List instead? I notice in the Stack documentation there is no method for removing the oldest (bottom)item from the stack, but perhaps I am missing something
https://msdn.microsoft.com/en-us/library/3278tedw(v=vs.100).aspx
What I need is all the functionality of the (Javascript only) Array class but in C#.
2nd Can anyone help with actual syntax using either approach? Any help appreciated!
You've probably missed the Queue data structure. With it, you can put new elements to the end and delete old ones from the front.
Additionally, you don't need to look at all the elements in the array to compute the average if there are constantly 10 elements. Knowing the previous average you can compute the new average like this:
newAvg = oldAvg + (newElem - deletedElem)/10;
or more shortly:
avg += (newElem - deletedElem)/10;
You could use the generic Queue<T> collection to store the values:
var queue = new Queue<float>();
queue.Enqueue(1.0f); // pushes new item
queue.Dequeue(); // removes oldest item
To obtain the average, use the LINQ Average() extension method:
var average = queue.Average();
Stacks are LIFO(Last In First Out).
If you want to remove the oldest value, then you'd want to use a queue (First In First Out).
I am new to C#.
Is it possible to get stack items by index like we can do in Lists in C#?
Thanks,
You can achieve it using LINQ:
Stack<int> stack = new Stack<int>();
stack.Push(1);
stack.Push(2);
stack.Push(3);
stack.Push(4);
int top = stack.ElementAt(0); // Returns 4
int next = stack.ElementAt(1); // Returns 3
However, if you find youself attempting to access the elements on a stack by index, then you are certainly doing something wrong, and you should redesign your solution.
It is possible using ElementAt() as shown by Matias. You can also use Peek to see what is on top without popping it. You can also convert to an array and get a value by index that way.
var s = new Stack<int>();
s.Push(1);
s.Push(2);
var value = s.ToArray()[1];
You should ask yourself whether this is wise, though. All you will ever be able to do is get a snapshot of the Stack at a point in time. There are also concurrency issues to consider.
UPDATE:
Seems like Matias and I came up with very similar answers. His is a more correct answer as to what the question asks. The ToArray() approach gives you a consistent snapshot that may be a bit more stable. Subsequent calls to ElementAt() may give you different answers and may throw an exception if the stack has been popped in between calls.
It is possible to chose the element of the stack by index by calling ElementAt<T>(Int32) or ElementAtOrDefault(Int32) methods.
As a side note, if you're new to C#, always try to find the answers at
MSDN
github
referencesource.microsoft.com
It's often way faster and more reliable than to look for the information on SO =)
I am stepping through a large list of object to do some stuff regarding said objects in the list.
During my iteration, I will remove some objects from the list depending on certain criteria.
Once all is done, I need to update the UI regarding the number of objects in my list. (List of T).
QUESTION:
When I call list.count, does .net actually iterate through the list to
count it, or does it store the count as a property/variable?
If .net physically re-iterates through the list, I may just as well keep a counter on my own iteration through the list, and save the overhead?
Thanks
It simply keeps an internal int to track the number of items. So no iteration.
The documentation says retrieving Count is an O(1) operation:
http://msdn.microsoft.com/en-us/library/27b47ht3%28v=vs.110%29.aspx
You can see for yourself:
http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs
List is implemented as an array list, and it keeps track of its own size, so invoking the .Count property doesn't require any iteration.
If you call the LINQ .Count() extension method, this will check whether the underlying IEnumerable<> implements ICollection (which a List<> does), and use the .Count property on that interface if possible. So this won't cause any iteration to occur either.
Incidentally, there are other problems you're going to encounter if you attempt to remove items from your list while iterating through it. It's not really clear how iteration should behave when you are removing elements out from under the iterator, so List<>s will avoid this issue entirely by throwing an exception if the list has been modified since its enumerator was created.
You can use a decompiler, such as the freely-available ILSpy, to answer these questions. If you're referring to the List<T> type, then the Count getter simply involves reading a field:
public int Count
{
get { return this._size; }
}
As stated here under the remarks tab
http://msdn.microsoft.com/en-us/library/27b47ht3(v=vs.110).aspx
Retrieving the value of this property is an O(1) operation.
Which means no iteration is occurring.
You tagged your question with both vb.net and c#, so in reply to "If .net physically re-iterates through the list, I may just as well keep a counter on my own iteration through the list, and save the overhead?"
If your iteration is with a For i = first To last then VB.NET will evaluate first and last when it enters the loop:
Dim first As Integer = 1
Dim last As Integer = 3
For i = first To last
Console.Write(i.ToString() & " ")
last = -99
Next
outputs: 1 2 3
If you do the equivalent in C#, first and last are evaluated on every iteration:
int first = 1;
int last = 1;
for (int i = first; i <= last; i++)
{
Console.Write(i.ToString() + " ");
last = -99;
}
outputs: 1
If your .Count() function/property is expensive to evaluate and/or you don't want it to be re-evaluated on each iteration (for some other reason), then in C# you could assign it to a temporary variable.
I have
string[] pkgratio= "1:2:6".Split(':');
var items = pkgratio.OrderByDescending(x => x);
I want to select the middle value and have come up with this. Is this a correct way to select the second value in an IEnumberable?
pkgratio.Skip(1).Take(1).First();
While what you have works, the most straightforward way would be to use the array's index and reference the second item (at index 1 since the index starts at zero for the first element): pkgratio[1]
Console.WriteLine(pkgratio[1]);
A more complete example:
string[] pkgratio = "1:2:6".Split(':');
for (int i = 0; i < pkgratio.Length; i++)
Console.WriteLine(pkgratio[i]);
With an IEnumerable<T> what you have works, or you could directly get the element using the ElementAt method:
// same idea, zero index applies here too
var elem = result.ElementAt(1);
Here is your sample as an IEnumerable<string>. Note that the AsEnumerable() call is to emphasize the sample works against an IEnumerable<string>. You can actually use ElementAt against the string[] array result from Split, but it's more efficient to use the indexer shown earlier.
var pkgratio = "1:2:6".Split(':').AsEnumerable();
Console.WriteLine(pkgratio.ElementAt(1));
I don't think you need to .Take(1).
pkgratio.Skip(1).First()
pkgratio.ElementAt(1); for your scenario.
However, your method is only applicable if you were using some data that implemented IQueryable or you needed to take a range of items starting at a specific index eg:
pkgratio.Skip(5).Take(10);
Well, the Take(1) isn't strictly necessary if you're going to just First() it, so I might go with
pkgratio.Skip(1).First();
However, that First() will throw an exception if there no value, so you might want to try FirstOrDefault() and then check for null.
I have an array of items that are time sensitive. After an amount of time, the last item needs to fall off and a new item is put at the beginning.
What is the best way to do this?
I would suggest using a queue, just a special instance of an array or list. When your timed event occurs, pop the last item from the queue, and then push your new item on.
Probably the easiest way to do this with an array is to use a circular index. Rather than always looking at array[n], you would reference array[cIndex] (where cIndex referrs to the item in the array being indexed (cIndex is incremented based on the arraySize (cIndex % arraySize)).
When you choose to drop the oldest item in the array, you would simply reference the element located at ((cIndex + (arraySize - 1)) % arraySize).
Alternatively, you could use a linkedList approach.
Use a Queue instead.
By using a Queue, preferably one implemented using a linked-list.
Have a look at using a Queue rather than a simple array.
A queue would work if there a fixed number of items.
Given that the 'amount of time' is known, how about a SortedDictionary with a DateTime key and override the Add method to remove all items with keys that are too old.
LinkedList<T> has AddFirst and RemoveLast members that should work perfectly.
EDIT: Looking at the Queue docs, it seems they use an internal array. As long as the implementation uses a circular-array type algorithm performance should be fine.
In csharp 3 you can do:
original = new[] { newItem }.Concat(
original.Take(original.Count() - 1)).ToArray()
But you are probably better off using a specialised datastructure
Queue is great for FIFO arrays. For generic array handling, use List(T)'s
Insert(0, x) and RemoveAt(0) methods to put or remove items in front of the list, for example.
Technically you need a deque. A queue has items pushed and popped off one end only. A deque is open at both ends.
Most languages will allow array manipulation, just remove the first element and put another one on the end.
Alternatively you can shift every element, by looping. Just replace each element (starting from the oldest) with its neighbour. Then place the new item in the last element.
If you know that your deque won't go above a certain size, then you can make it circular. You'll need two pointers to tell you where the two ends are though. Adding and removing items, will increase/decrease your pointers accordingly. You'll have to detect a buffer overflow condition (i.e. your pointers 'cross'). And you'll have to use modular arithmetic so your pointers go in a circle around the array.
Or you could time stamp each element in the array and remove them when they become too 'old'. You can either do this by keeping a separate array indexed in the same way, or by having an array of two element arrays, with the time stamp stored in one of the sub-elements.
If you're looking for the fastest way of doing this, it's going to be a circular array: you keep track of your current position in the array (ndx), and the end of the array (end), so when you insert an item, you implicitly eliminate the oldest item.
A circular array is the fastest implementation of a fixed-size queue that I know of.
For example, in C/C++ it would look like this for ints (quitting when you get a 0):
int queue[SIZE];
int ndx=0; // start at the beginning of the array
int end=SIZE-1;
int newitem;
while(1){
cin >> newitem;
if(!newitem) // quit if it's a 0
break;
if(ndx>end) // need to loop around the end of the array
ndx=0;
queue[ndx] = newitem;
ndx++
}
Lots of optimization could be done, but if you want to built it yourself, this is the fastest route.
If you don't care about performance, use a shipped Queue object because it should be generalized.
It may or may not be optimized, and it may not support a fixed size list, so be sure to check the documentation on it before using.