the data type needs to be optimized for performance, only sequential
add/remove is nessesary.
any suggestions?
Tem
how is it performance wise?
"Family Tree Mike" <FamilyT...@discussions.microsoft.com> wrote in
message news:D9869840-DB01-4CA6...@microsoft.com...
e.g. Person[][] mydata = new Person[9][];
mydata[0] = new Person[4];
mydata[1] = new Person[n];
HTH
Kalpesh
On Apr 7, 8:41 pm, "Tem" <tem1...@yahoo.com> wrote:
> thanks. let me try that.
>
> how is it performance wise?
>
> "Family Tree Mike" <FamilyTreeM...@discussions.microsoft.com> wrote in
> messagenews:D9869840-DB01-4CA6...@microsoft.com...
<shahka...@gmail.com> wrote in message
news:1fc16e47-9300-4fe4...@e10g2000prf.googlegroups.com...
> I need to be able to change the size of the array as needed. can this be
> done with jagged array?
It can be done as easily as it can be with any array. That is, not
conveniently, but possible.
If you want to be able to easily add and delete elements in the
collections, then using List<T> will be better than an array, just as it
would be for the more usual single-dimension collections.
As far as performance goes, if your requirement is to be able to resize
the collections, the the List<T> class is likely to be faster. Assuming
you allocate and copy a new array any time you have to add an element, the
List<T> will be orders of magnitude faster for any size collection where
the speed of the operation would be noticeable, since most of the time
adding an element to a List<T> doesn't involve copying any data except the
one element.
Likewise, if you're using similarly simple techniques to delete or insert
elements, the cost for an array will on average be twice that as for a
List<T> (again, an array would require allocating and copying an entire
new array, whereas with List<T> it would only have to copy, on average,
half the elements of the collection).
In any case, you should start out using the data structure that most
closely fits your need. In this case, that appears to be List<T>. As
long as it performs acceptably, then that's the right implementation to
use. If it doesn't, then you can consider other solutions that aren't as
closely representative of your actual algorithm in order to get better
performance.
Pete
List<List<object>> is good but i need to fix the size of one dimension
is there such thing as an array of List<>?
"Peter Duniho" <NpOeS...@nnowslpianmk.com> wrote in message
news:op.t894y...@petes-computer.local...
Basically, to minimise bloat, I've wrapped a List<T> to linearize an
arary - i.e. an array [3, *] would be a list where the first 3 values
are row 0, the next 3 are row 1, etc.
Then 'cos I was still bored, I wrapped this with a custom view so that
you can throw it at a grid (you can edit cells, but not add rows) or
single binding - and added change noification.
It should do most what you need!!!!
Marc
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
class Program
{
static void Main()
{
Matrix<int> grid = new
Matrix<int>(MatrixOrientation.FixedWidth, 10, 5);
grid[2, 2] = 5;
grid.Add(new int[] {1,2,3,4,5,6,7,8,9,0});
Application.EnableVisualStyles();
Application.Run(new Form
{
Controls = {
// demo list (multi) binding
new DataGridView {
Dock = DockStyle.Fill,
DataSource = grid
},
// demo list (single) binding
new TextBox {
Dock = DockStyle.Bottom,
DataBindings = { {"Text", grid, "Col3"}}
}
},
// demo single row binding
DataBindings = {{"Text", grid.DefaultView[2], "Col2"}}
});
}
}
public static class ClassExt
{
public static void CheckNull<T>(this T value, string paramName)
where T : class
{
if (value == null) throw new ArgumentNullException(paramName);
}
}
public enum MatrixOrientation
{
FixedWidth, FixedHeight
}
public class MatrixChangedEventArgs : EventArgs
{
private readonly int x, y;
public int X { get { return x; } }
public int Y { get { return y; } }
public MatrixChangedEventArgs(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Matrix<T> : IListSource
{
public override string ToString()
{
return string.Format("{0}[{1},{2}]", typeof(T).Name, Width,
Height);
}
public event EventHandler<MatrixChangedEventArgs> ValueChanged;
protected void OnValueChanged(int x, int y)
{
if (ValueChanged != null)
{
ValueChanged(this, new MatrixChangedEventArgs(x, y));
}
}
private readonly int fixedSize;
private readonly MatrixOrientation orientation;
public MatrixOrientation Orientation { get { return orientation; } }
private readonly List<T> list;
public Matrix(MatrixOrientation orientation, int width, int height)
{
switch (orientation)
{
case MatrixOrientation.FixedHeight:
fixedSize = height;
break;
case MatrixOrientation.FixedWidth:
fixedSize = width;
break;
default:
throw new ArgumentOutOfRangeException("orientation");
}
this.orientation = orientation;
CheckDimension(width, orientation ==
MatrixOrientation.FixedWidth, "width");
CheckDimension(height, orientation ==
MatrixOrientation.FixedWidth, "height");
list = new List<T>(width * height);
AddRange(orientation == MatrixOrientation.FixedWidth ? height :
width);
}
public void TrimExcess()
{
list.TrimExcess();
}
private void CheckDimension(int size, bool disallowEqual, string
paramName)
{
if (size < 0) throw new ArgumentOutOfRangeException(paramName,
"Dimension cannot be negative");
if (size == 0 && disallowEqual) throw new
ArgumentOutOfRangeException(paramName, "Dimension cannot be zero");
}
public Matrix(MatrixOrientation orientation, int fixedSize)
: this(orientation,
orientation == MatrixOrientation.FixedWidth ? fixedSize : 0,
orientation == MatrixOrientation.FixedHeight ? fixedSize : 0)
{
}
public void Clear()
{
list.Clear();
}
private int Linearize(int x, int y)
{
if (orientation == MatrixOrientation.FixedWidth)
{
if (x < 0 || y < 0 || x >= fixedSize) throw new
ArgumentOutOfRangeException();
return (y * fixedSize) + x;
}
else
{
if (y < 0 || y < 0 || y >= fixedSize) throw new
ArgumentOutOfRangeException();
return (x * fixedSize) + y;
}
}
public T this[int x, int y]
{
get
{
return list[Linearize(x, y)];
}
set
{
list[Linearize(x, y)] = value;
OnValueChanged(x, y);
}
}
public void Add() { AddRange(1); }
public void Add(T[] values)
{
values.CheckNull("values");
if (values.Length != fixedSize) throw new
ArgumentException("Array must be the same size as the fixed dimension",
"values");
list.AddRange(values);
}
public void AddRange(int count) {
CheckDimension(count, false, "count");
count *= fixedSize;
while (count-- > 0)
{
list.Add(default(T));
}
}
public void Remove() { RemoveRange(1); }
public void RemoveRange(int count)
{
CheckDimension(count, false, "count");
count *= fixedSize;
list.RemoveRange(list.Count - count, count);
}
public int FixedSize { get { return fixedSize; } }
public int DynamicSize { get { return list.Count / fixedSize; } }
public int Width
{
get
{
return orientation == MatrixOrientation.FixedWidth
? FixedSize : DynamicSize;
}
}
public int Height
{
get
{
return orientation == MatrixOrientation.FixedHeight
? FixedSize : DynamicSize;
}
}
#region IListSource Members
bool IListSource.ContainsListCollection
{
get { return false; }
}
System.Collections.IList IListSource.GetList()
{
return DefaultView;
}
#endregion
private MatrixView<T> defaultView;
public MatrixView<T> DefaultView {
get {
if(defaultView == null) {
defaultView = new MatrixView<T>(this, false);
}
return defaultView;
}
}
}
public class MatrixView<T> : ITypedList, IList<MatrixViewRow<T>>, IList,
IBindingList
{
private readonly Matrix<T> parent;
private readonly bool transposed;
public MatrixView<T> Transpose()
{
return new MatrixView<T>(parent, !transposed);
}
internal MatrixView(Matrix<T> parent, bool transposed)
{
parent.CheckNull("parent");
this.parent = parent;
this.transposed = transposed;
}
public PropertyDescriptorCollection GetColumns()
{
int width = Width;
List<PropertyDescriptor> props = new
List<PropertyDescriptor>(width);
for (int i = 0; i < width; i++)
{
props.Add(new MatrixViewCol<T>(this, i));
}
return new PropertyDescriptorCollection(props.ToArray(), true);
}
PropertyDescriptorCollection
ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
{
if (listAccessors != null && listAccessors.Length != 0)
{
throw new NotSupportedException();
}
return GetColumns();
}
string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
{
return "";
}
public void Clear()
{
parent.Clear();
}
public int IndexOf(MatrixViewRow<T> slice)
{
slice.CheckNull("slice");
return slice.Index;
}
void IList<MatrixViewRow<T>>.Insert(int index, MatrixViewRow<T> slice)
{
throw new NotSupportedException();
}
void IList<MatrixViewRow<T>>.RemoveAt(int index)
{
throw new NotSupportedException();
}
bool ICollection<MatrixViewRow<T>>.Contains(MatrixViewRow<T> slice)
{
if (slice == null) return false;
return slice.Index >= 0 && slice.Index < Height;
}
public int Width
{
get { return transposed ? parent.Height : parent.Width; }
}
public int Height
{
get { return transposed ? parent.Width: parent.Height; }
}
public MatrixViewRow<T> this[int index]
{
get { return new MatrixViewRow<T>(this, index); }
set { throw new NotSupportedException(); }
}
void ICollection<MatrixViewRow<T>>.Add(MatrixViewRow<T> slice)
{
throw new NotSupportedException();
}
bool ICollection<MatrixViewRow<T>>.Remove(MatrixViewRow<T> slice)
{
throw new NotSupportedException();
}
public int Count { get { return Height; } }
bool ICollection<MatrixViewRow<T>>.IsReadOnly { get { return false; } }
bool IList.IsReadOnly { get { return ThisList.IsReadOnly; } }
bool IList.IsFixedSize { get { return true; } }
public IEnumerator<MatrixViewRow<T>> GetEnumerator()
{
for (int i = 0; i < Height; i++)
{
yield return this[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
int IList.Add(object obj)
{
MatrixViewRow<T> slice = (MatrixViewRow<T>)obj;
ThisList.Add(slice);
return slice.Index;
}
bool IList.Contains(object obj)
{
return ThisList.Contains((MatrixViewRow<T>)obj);
}
int IList.IndexOf(object obj)
{
return IndexOf((MatrixViewRow<T>)obj);
}
void IList.Remove(object obj)
{
ThisList.Remove((MatrixViewRow<T>)obj);
}
private IList<MatrixViewRow<T>> ThisList { get { return this; } }
void IList.Insert(int index, object obj)
{
ThisList.Insert(index, (MatrixViewRow<T>)obj);
}
void IList.RemoveAt(int index)
{
ThisList.RemoveAt(index);
}
object IList.this[int index]
{
get { return this[index]; }
set { this[index] = (MatrixViewRow<T>)value; }
}
object ICollection.SyncRoot
{
get { return parent; }
}
bool ICollection.IsSynchronized
{
get { return false; }
}
void ICollection.CopyTo(Array values, int index)
{
for (int i = 0; i < Height; i++)
{
values.SetValue(this[i], i + index);
}
}
void ICollection<MatrixViewRow<T>>.CopyTo(MatrixViewRow<T>[]
values, int index)
{
for (int i = 0; i < Height; i++)
{
values[i + index] = this[i];
}
}
public bool IsTransposed { get { return transposed; } }
public string RowName(int index)
{
return (IsTransposed ? "Col" : "Row") + index.ToString();
}
public string ColName(int index)
{
return (IsTransposed ? "Row" : "Col") + index.ToString();
}
public T this[int colIndex, int rowIndex]
{
get { return IsTransposed ? parent[rowIndex, colIndex] :
parent[colIndex, rowIndex]; }
set
{
if (IsTransposed)
{
parent[rowIndex, colIndex] = value;
}
else
{
parent[colIndex, rowIndex] = value;
}
}
}
bool IBindingList.AllowNew { get { return false; } }
bool IBindingList.AllowRemove { get { return false; } }
bool IBindingList.AllowEdit { get { return true; } }
object IBindingList.AddNew()
{
throw new NotSupportedException();
}
void IBindingList.AddIndex(PropertyDescriptor property) { }
void IBindingList.RemoveIndex(PropertyDescriptor property) { }
bool IBindingList.SupportsSorting { get { return false; } }
void IBindingList.ApplySort(PropertyDescriptor property,
ListSortDirection direction)
{
throw new NotSupportedException();
}
PropertyDescriptor IBindingList.SortProperty { get { return null; } }
ListSortDirection IBindingList.SortDirection { get { return
ListSortDirection.Ascending; } }
bool IBindingList.IsSorted { get { return false; } }
void IBindingList.RemoveSort() { }
bool IBindingList.SupportsSearching { get { return false; } }
int IBindingList.Find(PropertyDescriptor property, object obj)
{
throw new NotSupportedException();
}
bool IBindingList.SupportsChangeNotification { get { return true; } }
private ListChangedEventHandler listChanged;
public event ListChangedEventHandler ListChanged
{
add
{
bool first = listChanged == null;
listChanged += value;
if (first && listChanged != null) parent.ValueChanged +=
ListChangedHandler;
}
remove {
listChanged -= value;
if (listChanged == null) parent.ValueChanged -=
ListChangedHandler;
}
}
private void OnListChanged(int index) {
if(listChanged != null) {
listChanged(this, new
ListChangedEventArgs(ListChangedType.ItemChanged, index));
}
}
private void OnRowChanged(int index) {
EventHandler handler;
if (rowHandlers != null && rowHandlers.TryGetValue(index, out
handler))
{
handler(this, EventArgs.Empty);
}
}
private void ListChangedHandler(object sender,
MatrixChangedEventArgs args)
{
int index = IsTransposed ? args.X : args.Y;
OnListChanged(index);
}
private void RowChangedHandler(object sender,
MatrixChangedEventArgs args)
{
int index = IsTransposed ? args.X : args.Y;
OnRowChanged(index);
}
internal void AddRowHandler(int index, EventHandler handler)
{
if (handler == null) return;
if (rowHandlers == null)
{
rowHandlers = new Dictionary<int, EventHandler>();
parent.ValueChanged += RowChangedHandler;
}
EventHandler value;
rowHandlers.TryGetValue(index, out value);
value += handler;
rowHandlers[index] = value;
}
internal void RemoveRowHandler(int index, EventHandler handler)
{
if (handler == null || rowHandlers == null) return;
EventHandler value;
if (rowHandlers.TryGetValue(index, out value))
{
value -= handler;
if (value == null)
{
rowHandlers.Remove(index);
if (rowHandlers.Count == 0)
{
rowHandlers = null;
parent.ValueChanged -= RowChangedHandler;
}
}
else
{
rowHandlers[index] = value;
}
}
}
private Dictionary<int, EventHandler> rowHandlers;
}
public class MatrixViewRow<T> : ICustomTypeDescriptor
{
private readonly int index;
public int Index { get { return index; } }
private readonly MatrixView<T> parent;
internal MatrixViewRow(MatrixView<T> parent, int index)
{
if (index < 0) throw new ArgumentOutOfRangeException("index");
parent.CheckNull("parent");
this.index = index;
this.parent = parent;
}
public override string ToString()
{
return parent.RowName(index);
}
#region ICustomTypeDescriptor Members
private static Type RowType { get { return
typeof(MatrixViewRow<T>); } }
AttributeCollection ICustomTypeDescriptor.GetAttributes()
{
return TypeDescriptor.GetAttributes(RowType);
}
string ICustomTypeDescriptor.GetClassName()
{
return TypeDescriptor.GetClassName(RowType);
}
string ICustomTypeDescriptor.GetComponentName()
{
return TypeDescriptor.GetComponentName(RowType);
}
TypeConverter ICustomTypeDescriptor.GetConverter()
{
return TypeDescriptor.GetConverter(RowType);
}
EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(RowType);
}
PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(RowType);
}
object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(RowType, editorBaseType);
}
EventDescriptorCollection
ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(RowType, attributes);
}
EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
{
return TypeDescriptor.GetEvents(RowType);
}
PropertyDescriptorCollection
ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
{
return ThisDesc.GetProperties();
}
private ICustomTypeDescriptor ThisDesc { get { return this; } }
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
{
return parent.GetColumns();
}
object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
{
return this;
}
#endregion
}
internal class MatrixViewCol<T> : PropertyDescriptor
{
public override string ToString()
{
return Name;
}
private static readonly Attribute[] fixedAttribs = new Attribute[0];
private readonly MatrixView<T> parent;
private int index;
public MatrixViewCol(MatrixView<T> parent, int index) : base(parent
== null ? "None" : parent.ColName(index), fixedAttribs)
{
parent.CheckNull("parent");
this.parent = parent;
this.index = index;
}
public override Type ComponentType
{
get { return typeof(MatrixViewRow<T>); }
}
public override bool IsReadOnly
{
get { return false; }
}
public override Type PropertyType
{
get { return typeof(T); }
}
public override bool CanResetValue(object component)
{
return true;
}
public override void ResetValue(object component)
{
SetValue(component, default(T));
}
private MatrixViewRow<T> Row(object component)
{
return ((MatrixViewRow<T>)component);
}
public override void SetValue(object component, object value)
{
parent[index, Row(component).Index] = (T)value;
}
public override object GetValue(object component)
{
return parent[index, Row(component).Index];
}
public override bool ShouldSerializeValue(object component)
{
return
!EqualityComparer<T>.Default.Equals((T)GetValue(component), default(T));
}
protected override object GetInvocationTarget(Type type, object
instance)
{
return base.GetInvocationTarget(type, instance);
}
public override bool SupportsChangeEvents
{
get { return true; }
}
public override void AddValueChanged(object component, EventHandler
handler)
{
parent.AddRowHandler(Row(component).Index, handler);
}
public override void RemoveValueChanged(object component,
EventHandler handler)
{
parent.RemoveRowHandler(Row(component).Index, handler);
}
}
private List<string> [ ] arrListString = new List<string> [15];
Make sure however that you initialize each array element to a new
List<string>:
for (int idx = 0; idx < 15; ++idx)
arrListString[idx] = new List<string>();
The linearized Matrix<T> I posted earlier handles all this in a single
list, and allows you to have either axis pinned. You could probably
loser all the ITypedList stuff without too much pain, though ;-p
Marc
Thanks for sharing it,
Does anyone know how to limit the capacity of a regular List<>?
"Marc Gravell" <marc.g...@gmail.com> wrote in message
news:%23GRr1UX...@TK2MSFTNGP02.phx.gbl...