kejpa Posted November 8, 2004 Posted November 8, 2004 Hi, I'm about to build a filter class in which I will hold a small number (10-50) of pairs (x,y). I need to calculate average, sum and some other statistical functions on the pairs. The number of pairs is fixed for each object that holds the filter but it has to be changeable from outside the class. In VB6 we used a Collection to do this, I'm curious to wheather there's a better way now (and in vb2005). Should I inherit from "Collection" or just have an internal collection? Is Queue the right object? Regards /Kejpa Quote
mskeel Posted November 8, 2004 Posted November 8, 2004 ArrayLists are pretty cool. Their kind of like a dynamic array meets a linked list. Quote
Mike_R Posted November 8, 2004 Posted November 8, 2004 They are internally implemented as an Array. But it is an Array of Object so that it can handle "anything". When passing in Value Types there is a pretty big hit to performance versus using a Strong Typed Array, due to the Boxing and Unboxing required. That said, I think that for ease of use here, an ArrayList would be a very good choice, unless speed were of critical importance. You could pass in Point() Objects to hold your pairs. Quote Posting Guidelines Avatar by Lebb
mskeel Posted November 8, 2004 Posted November 8, 2004 Is there an object that will act as a linked list in .Net? I would think just a linked list implimentation of the IList interface... Quote
kejpa Posted November 9, 2004 Author Posted November 9, 2004 That said' date=' I think that for ease of use here, an ArrayList would be a very good choice, unless speed were of critical importance. You could pass in Point() Objects to hold your pairs.[/quote'] Ease of use is nice, speed is critical when handling some 50 filter objects twice a second... Previously (with VB6) we have used a class with an collection to hold the items, before that we had an array. Both worked well and so does the class I'm currently using, but I think using a collection has some overhead, which I would like to get rid of if possible. Thank you for your time, any other ideas and I'm all ears /Kejpa Quote
Joe Mamma Posted November 9, 2004 Posted November 9, 2004 (edited) A quick hack. . . keeps aggregate values as items are inserted and removed, Implements IEnumerable, ICollection, IList C# as I don't do vb for stuff like this. . . too clunky using System; using System.Drawing; using System.Collections; namespace ObjTec.Collections { public class PointCollection : IList, IEnumerable, ICollection { protected ArrayList _data = new ArrayList(); DoublePoint _avg = new DoublePoint(); DoublePoint _total = new DoublePoint(); DoublePoint _min = new DoublePoint(); DoublePoint _max = new DoublePoint(); public DoublePoint Average { get { return _avg; } } public DoublePoint Total { get { return _total; } } public DoublePoint Minimum { get { return _min; } } public DoublePoint Maximum { get { return _max; } } public PointCollection() { } public IEnumerator GetEnumerator() { return new PointCollectionEnumerator(this); } public int Add(object value) { this.Insert(_data.Count, value); return _data.Count-1; } public void Remove(object value) { int n = _data.IndexOf(value); this.RemoveAt(n); } public void Clear() { _data.Clear(); _avg.X = 0; _avg.Y = 0; _min.X = 0; _min.Y = 0; _max.X = 0; _max.Y = 0; _total.X = 0; _total.Y = 0; } public bool Contains(object value) { return _data.Contains(value); } public int IndexOf(object value) { return _data.IndexOf(value); } public void Insert(int index, object value) { if (value.GetType() != typeof(DoublePoint)) throw new ArgumentException("Item must be a DoublePoint"); _data.Insert(index, value); DoublePoint p = (DoublePoint) value; _avg.X += (p.X / _data.Count); _avg.Y += (p.Y / _data.Count); _min.X = Math.Min(_min.X,p.X); _min.Y = Math.Min(_min.Y,p.Y); _max.X = Math.Max(_max.X,p.X); _max.Y = Math.Max(_max.Y,p.Y); _total.X += p.X; _total.Y += p.Y; } private enum Aggregate {Min, Max, Tot, Avg} private double Range(bool isX, Aggregate aggr) { double val; switch (aggr) { case Aggregate.Min: val = Double.MaxValue; break; case Aggregate.Max: val = Double.MinValue; break; default: val = 0;break; } foreach (object p in _data) switch (aggr) { case Aggregate.Min: val = Math.Min(val, isX ? ((DoublePoint)p).X : ((DoublePoint)p).Y); break; case Aggregate.Max: val = Math.Max(val, isX ? ((DoublePoint)p).X : ((DoublePoint)p).Y) ; break; case Aggregate.Avg: val += (isX ? ((DoublePoint)p).X : ((DoublePoint)p).Y) / _data.Count;break; default: val += isX ? ((DoublePoint)p).X : ((DoublePoint)p).Y; break; } return val; } private double MinX() { return Range(true, Aggregate.Min); } private double MaxX() { return Range(true, Aggregate.Max); } private double MinY() { return Range(false, Aggregate.Min); } private double MaxY() { return Range(false, Aggregate.Max); } private double AvgX() { return Range(true, Aggregate.Avg); } private double AvgY() { return Range(false, Aggregate.Avg); } private double TotX() { return Range(true, Aggregate.Tot); } private double TotY() { return Range(false, Aggregate.Tot); } public void RemoveAt(int index) { object o = (DoublePoint)( index < _data.Count ? this[index]: null); if (o == null) return; DoublePoint p = (DoublePoint) o; _data.RemoveAt(index); _min.X = p.X == _min.X ? MinX() : _min.X ; _min.X = p.X == _min.X ? MinX() : _min.X ; _min.X = p.X == _min.X ? MinX() : _min.X ; _min.X = p.X == _min.X ? MinX() : _min.X ; _avg.X -= (p.X / _data.Count); _avg.Y -= (p.Y / _data.Count); _total.X -= p.X; _total.Y -= p.Y; } public bool IsFixedSize { get { return false; } } public bool IsReadOnly { get { return false; } } public object this[int index] { get { return _data[index]; } set { RemoveAt(index); Insert(index, value); } } public void CopyTo(Array array, int index) { // not implemented } public int Count { get { return _data.Count; } } public bool IsSynchronized { get { return false; } } public object SyncRoot { get { return this; } } public virtual void Sort() { _data.Sort(); } public virtual void Sort(IComparer comparer) { _data.Sort(comparer); } public virtual void Sort(int index, int count, IComparer comparer) { _data.Sort(index, count, comparer); } } public class PointCollectionEnumerator : System.Collections.IEnumerator { PointCollection _pc; int _current; public PointCollectionEnumerator(PointCollection pc) { _pc = pc; _current = 0; } public void Reset() { _current = 0; } public object Current { get { if (_current < _pc.Count) { System.Collections.IList il = _pc; return il[_current]; } else return null; } } public bool MoveNext() { _current++; return _current < _pc.Count; } } public object DoublePoint: IComparable { public double X; public double Y; public int CompareTo(object obj) { Point p = (DoublePoint) obj; return Math.Sqrt( Math.Pow(X, 2) + Math.Pow(Y, 2) ).CompareTo( Math.Sqrt( Math.Pow(p.X, 2) + Math.Pow(p.Y, 2) )); } } } Edited November 9, 2004 by Joe Mamma Quote Joe Mamma Amendment 4: The right of the people to be secure in their persons, houses, papers, and effects, against unreasonable searches and seizures, shall not be violated, and no warrants shall issue, but upon probable cause, supported by oath or affirmation, and particularly describing the place to be searched, and the persons or things to be seized. Amendment 9: The enumeration in the Constitution, of certain rights, shall not be construed to deny or disparage others retained by the people.
Joe Mamma Posted November 9, 2004 Posted November 9, 2004 By the way. . .vb collections blow chunks! real slow! nothing slower than a key compare to find an item. as opposed by reference compare. I could be wrong, but that is my overall impression of working with them over the past 6 months. god VB 6 is just plain awful! I don't know how people put up with it. no inheritance no delegation no canvas no client area yuck!!! Quote Joe Mamma Amendment 4: The right of the people to be secure in their persons, houses, papers, and effects, against unreasonable searches and seizures, shall not be violated, and no warrants shall issue, but upon probable cause, supported by oath or affirmation, and particularly describing the place to be searched, and the persons or things to be seized. Amendment 9: The enumeration in the Constitution, of certain rights, shall not be construed to deny or disparage others retained by the people.
Joe Mamma Posted November 9, 2004 Posted November 9, 2004 one last thing. . . using my code, store all your DoublePoint instances in a master ArrayList, use the PointCollection for storing references to the instances. Quote Joe Mamma Amendment 4: The right of the people to be secure in their persons, houses, papers, and effects, against unreasonable searches and seizures, shall not be violated, and no warrants shall issue, but upon probable cause, supported by oath or affirmation, and particularly describing the place to be searched, and the persons or things to be seized. Amendment 9: The enumeration in the Constitution, of certain rights, shall not be construed to deny or disparage others retained by the people.
kejpa Posted November 9, 2004 Author Posted November 9, 2004 A quick hack. . . C# as I don't do vb for stuff like this. . . too clunky Thanx Joe! Have to do it in vb though... As I'm not fluent in c# and as my boss can't spell anything else... I'll try to convert it myself ;) Once again, thanks a bunch. Regards Kejpa Quote
Joe Mamma Posted November 9, 2004 Posted November 9, 2004 Thanx Joe! Have to do it in vb though... As I'm not fluent in c# and as my boss can't spell anything else... I'll try to convert it myself ;) I am in the same position myself. Using VB6 as .NET is not NSA approved as of yet (Doing NISPOM security management for defense agencies.) Things take at least twzice as long to run and develop as opposed to delphi. The boss only speaks VB. Let me rephrase that. Wont even try to look at delphi. At any rate, in my insomnia, I thought of a couple of issues in my approach. the aggregates should not be initialized in the class, but set to null. If on insert, there are no points , instance the aggregate and copy the point to it, else calculate the values. On removing the last value, set the aggregates to null. Next, make the X and Y of the double points properties, and create an OnChangedX/OnChangedY event that is called when changing either property. The create a PointCollection RecalculateX/RecalculateY method. When inserting the point to a PointCollection, attach the RecalculateX and RecalculateY method to the DoublePoints event. on remove, detach the method. Once again, thanks a bunch. Regards Kejpa your quite welcome! Live to Code! Code to Live! Quote Joe Mamma Amendment 4: The right of the people to be secure in their persons, houses, papers, and effects, against unreasonable searches and seizures, shall not be violated, and no warrants shall issue, but upon probable cause, supported by oath or affirmation, and particularly describing the place to be searched, and the persons or things to be seized. Amendment 9: The enumeration in the Constitution, of certain rights, shall not be construed to deny or disparage others retained by the people.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.