473,414 Members | 1,636 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,414 software developers and data experts.

Referencing [,] element as [ ]?

I have a two-dimensional array with 6 x 7 elements. I'd like to be able to
reference the elements sequentially, as if the rows were laid end-to-end. I
know the Array.Length property will give me the length of the array as 42,
but I'd like to be able to reference specific elements. For example, I'd
like to be able to reference foo[3,2] as foo[24].

Is there any way to do this natively in C#? Right now I'm using a conversion
function that takes an index and returns a cell reference. I'd like to
eliminate the function, if I can. Thanks in advance.

--
David Veeneman
Foresight Systems
Jan 19 '06 #1
14 1473
Something like this?

foo[Math.Floor(24/7),24%7] // foo[24]

In C you could fo what you say, but they were just downright nasty memory
overruns that happened to work...

"David Veeneman" <da****@nospam.com> wrote in message
news:%2***************@TK2MSFTNGP12.phx.gbl...
I have a two-dimensional array with 6 x 7 elements. I'd like to be able to
reference the elements sequentially, as if the rows were laid end-to-end. I
know the Array.Length property will give me the length of the array as 42,
but I'd like to be able to reference specific elements. For example, I'd
like to be able to reference foo[3,2] as foo[24].

Is there any way to do this natively in C#? Right now I'm using a
conversion function that takes an index and returns a cell reference. I'd
like to eliminate the function, if I can. Thanks in advance.

--
David Veeneman
Foresight Systems

Jan 19 '06 #2
David Veeneman wrote:
I have a two-dimensional array with 6 x 7 elements. I'd like to be able to
reference the elements sequentially, as if the rows were laid end-to-end. I
know the Array.Length property will give me the length of the array as 42,
but I'd like to be able to reference specific elements. For example, I'd
like to be able to reference foo[3,2] as foo[24].

Is there any way to do this natively in C#? Right now I'm using a conversion
function that takes an index and returns a cell reference. I'd like to
eliminate the function, if I can. Thanks in advance.


I don't think so. Your best strategy may be to allocate your array as
a 43 element array. That way, the code that needs to deal with rows
and columns can call your product and sum methods, while the code that
can deal with vectors goes straight to the vector.

--
<http://www.midnightbeach.com>
Jan 19 '06 #3
David Veeneman wrote:
I have a two-dimensional array with 6 x 7 elements. I'd like to be able to
reference the elements sequentially, as if the rows were laid end-to-end. I
know the Array.Length property will give me the length of the array as 42,
but I'd like to be able to reference specific elements. For example, I'd
like to be able to reference foo[3,2] as foo[24].

Is there any way to do this natively in C#? Right now I'm using a conversion
function that takes an index and returns a cell reference. I'd like to
eliminate the function, if I can. Thanks in advance.


Just in case anyone else was investigating this line of enquiry - using
the IList indexer implementation for arrays doesn't work. For instance:

using System;
using System.Collections;

class Test
{
static void Main()
{
string[,] array = new string[10,20];
array[0,5] = "Hello";
array[3,4] = "There";

IList list = (IList)array;

Console.WriteLine (list[5]);
Console.WriteLine (list[64]);
}
}

compiles but gives the following result:
Unhandled Exception: System.ArgumentException: Array was not a
one-dimensional array.
at System.Array.GetValue(Int32 index)
at System.Array.System.Collections.IList.get_Item(Int 32 index)
at Test.Main()

(Using 2.0 and generics doesn't help either as far as I can see.)

Jon

Jan 19 '06 #4
On Wed, 18 Jan 2006 19:28:32 -0600, "David Veeneman"
<da****@nospam.com> wrote:
I have a two-dimensional array with 6 x 7 elements. I'd like to be able to
reference the elements sequentially, as if the rows were laid end-to-end.


That's not directly possible with .NET arrays, at least not in C#.
However, you could access the array with foreach -- the iterator will
loop through all elements sequentially, but you won't know the current
overall index unless you keep track of it yourself.
--
http://www.kynosarges.de
Jan 19 '06 #5
Christoph Nahr wrote:
I have a two-dimensional array with 6 x 7 elements. I'd like to be able to
reference the elements sequentially, as if the rows were laid end-to-end.
That's not directly possible with .NET arrays, at least not in C#.
However, you could access the array with foreach -- the iterator will
loop through all elements sequentially, but you won't know the current
overall index unless you keep track of it yourself.


In fact, it's not just C#. As far as I can tell, IL doesn't have any
direct instructions for accessing an array element unless the array is
actually a vector (in CLI terminology) - a single-dimensional array
with a lower bound of 0.
From the CLI spec (first edition, admittedly), section 4.7 of partition

III:

<quote>
The ldelem instruction loads the value of the element with index
'index' (of type int32 or native int) in the zero-based, one
dimensional array 'array' and places it on the top of the stack.
....
For one-dimesional arrays that aren't zero-based, and for
multi-dimensional arrays, the array class provides a Get method.
</quote>

Of course, it wouldn't be hard to write an ArrayUtil class which took
an arbitrary Array and an index, then use GetUpperBounds etc to access
the relevant element. It wouldn't be very efficient though...

Jon

Jan 19 '06 #6
I was afraid that was the case. For the benefit of anyone else researching
the question, here is the code I use to get a cell reference from an index
number. It assumes a 6 x 7 array:
private CellRef GetCellRefFromIndex(int index)
{
// Get the row number for the index passed in
int row = index / 7;

// Get the column number for the index passed in
int column = (index % 7) - 1;
if (column == -1) column = 6;

// Set return value
return new CellRef(row, column);
}
The code returns a CellRef, which is a custom struct:
private struct CellRef
{
public int Row;
public int Column;

public CellRef(int row, int column)
{
Row = row;
Column = column;
}
}


Jan 19 '06 #7
David Veeneman wrote:
// Get the column number for the index passed in
int column = (index % 7) - 1;
if (column == -1) column = 6;


Looks like 1 <= index <= 43. Fwiw,

int column = (index - 1) % 7;

should be more efficient than your code, with its conditional
statement.

--
<http://www.midnightbeach.com>
Jan 19 '06 #8
On Wed, 18 Jan 2006 19:28:32 -0600, "David Veeneman"
<da****@nospam.com> wrote:
I have a two-dimensional array with 6 x 7 elements. I'd like to be able to
reference the elements sequentially, as if the rows were laid end-to-end. I
know the Array.Length property will give me the length of the array as 42,
but I'd like to be able to reference specific elements. For example, I'd
like to be able to reference foo[3,2] as foo[24].

Is there any way to do this natively in C#? Right now I'm using a conversion
function that takes an index and returns a cell reference. I'd like to
eliminate the function, if I can. Thanks in advance.


You could wrap the underlying array in a class and provide two
separate indexers: [] and [,]. For reasons of speed I have used one
dimension rather than two for the underlying array. YMMV.

public class CellRefArray {
private int m_rows;
private int m_cols;
private CellRef[] m_CRArray;

// Constructor
public CellRefArray(int rows, int cols) {
m_rows = rows;
m_cols = cols;
m_CRArray = new CellRef[m_rows * m_cols];
}

// Indexer[]
public CellRef this[int i] {
get { return m_CRArray[i]; }
set { m_CRArray[i] = value; }
}

// Indexer[,]
public CellRef this[int r, int c] {
get { return m_CRArray[r * m_cols + c]; }
set { m_CRArray[r * m_cols + c] = value; }
}
}

You may want to add some range checking to the two indexers.

Depending on precisely what you want you might also want to add a
second constructor that takes an array[,] as parameter or a property
that returns an array[,].

rossum
--

The ultimate truth is that there is no ultimate truth
Jan 19 '06 #9
Jon Shemitz <jo*@midnightbeach.com> wrote:
David Veeneman wrote:
// Get the column number for the index passed in
int column = (index % 7) - 1;
if (column == -1) column = 6;


Looks like 1 <= index <= 43. Fwiw,

int column = (index - 1) % 7;

should be more efficient than your code, with its conditional
statement.


However, it's not equivalent. The index 0 would give column=-1 with
your code, but column=6 for David's. To make it equivalent, however
(for non-negative values of "index") you could use (index+6)%7 instead.

Alternatively, it would be worth trying Math.DivRem. I haven't
benchmarked it, so I've no idea whether it would be faster or not - but
if efficiency is critical, it's worth a try.

I'm not sure why David's subtracting one in the first place, however...
I don't think he should be doing so.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 19 '06 #10
Jon Skeet [C# MVP] <sk***@pobox.com> wrote:
Jon Shemitz <jo*@midnightbeach.com> wrote:
David Veeneman wrote:
// Get the column number for the index passed in
int column = (index % 7) - 1;
if (column == -1) column = 6;


Looks like 1 <= index <= 43. Fwiw,

int column = (index - 1) % 7;

should be more efficient than your code, with its conditional
statement.


However, it's not equivalent. The index 0 would give column=-1 with
your code, but column=6 for David's. To make it equivalent, however
(for non-negative values of "index") you could use (index+6)%7 instead.


Doh, sorry, missed the first line of your reply. Assuming a positive
value for index, your code is equivalent. Maybe I should just go to bed
now...

However, I still think there's a bug in David's code. Here's the
index/row/column values:

1/0/0
2/0/1
3/0/2
4/0/3
5/0/4
6/0/5
7/1/6 <-- Bug!
8/1/0
9/1/1
10/1/2
11/1/3
12/1/4
13/1/5
14/2/6 <-- Bug!

(etc)

Basically, if the index is to be treated as 1-based, it should be
treated that way consistently for both the row and the column.

(Personally I'd suggest just using a zero-based index to start with,
but there we go.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 19 '06 #11
"Jon Skeet [C# MVP]" wrote:
Looks like 1 <= index <= 43. Fwiw,

int column = (index - 1) % 7;

should be more efficient than your code, with its conditional
statement.
However, it's not equivalent. The index 0 would give column=-1 with
your code, but column=6 for David's.


Yes, this is why I assume he's using a 1-based index.
To make it equivalent, however
(for non-negative values of "index") you could use (index+6)%7 instead.


True.

--
<http://www.midnightbeach.com>
Jan 19 '06 #12
Why not just create your own collection class and implement the indexers
to do what you want?


rossum wrote:
On Wed, 18 Jan 2006 19:28:32 -0600, "David Veeneman"
<da****@nospam.com> wrote:
I have a two-dimensional array with 6 x 7 elements. I'd like to be able to
reference the elements sequentially, as if the rows were laid end-to-end. I
know the Array.Length property will give me the length of the array as 42,
but I'd like to be able to reference specific elements. For example, I'd
like to be able to reference foo[3,2] as foo[24].

Is there any way to do this natively in C#? Right now I'm using a conversion
function that takes an index and returns a cell reference. I'd like to
eliminate the function, if I can. Thanks in advance.


You could wrap the underlying array in a class and provide two
separate indexers: [] and [,]. For reasons of speed I have used one
dimension rather than two for the underlying array. YMMV.

public class CellRefArray {
private int m_rows;
private int m_cols;
private CellRef[] m_CRArray;

// Constructor
public CellRefArray(int rows, int cols) {
m_rows = rows;
m_cols = cols;
m_CRArray = new CellRef[m_rows * m_cols];
}

// Indexer[]
public CellRef this[int i] {
get { return m_CRArray[i]; }
set { m_CRArray[i] = value; }
}

// Indexer[,]
public CellRef this[int r, int c] {
get { return m_CRArray[r * m_cols + c]; }
set { m_CRArray[r * m_cols + c] = value; }
}
}

You may want to add some range checking to the two indexers.

Depending on precisely what you want you might also want to add a
second constructor that takes an array[,] as parameter or a property
that returns an array[,].

rossum
--

The ultimate truth is that there is no ultimate truth

Jan 19 '06 #13
John Murray <jm*****@pluck.com> wrote:
Why not just create your own collection class and implement the indexers
to do what you want?


Isn't that exactly what rossum did?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 19 '06 #14
Missed that one -- *grin*
Jon Skeet [C# MVP] wrote:
John Murray <jm*****@pluck.com> wrote:
Why not just create your own collection class and implement the indexers
to do what you want?


Isn't that exactly what rossum did?

Jan 20 '06 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Bosconian | last post by:
I've been researching this for hours and can't seem to find the right syntax. I need to retrieve a value of an array by referencing the element using a string variable. For example: $data...
1
by: JavaDeveloper | last post by:
Is it possible to reference another XSD file within an XSD file? What I'd like to do is have a fairly static XSD file which contains an element whose valid values change often reference a 2nd XSD...
2
by: Simon | last post by:
Am using the following code. <script language="JavaScript1.2"> function setquantity(productindex,productquantity) { //create the reference object irefname_none = eval("document." +...
5
by: Tim Johnson | last post by:
Hi: Is it possible to reference a table which contains a select list that has an event handler that modifies the table, without using the table ID? Example: <table id="SearchTable"> event...
11
by: Edd | last post by:
Hello all, I've made a data structure and an associated set of functions to enable me to store a dynamically-sized array of elements of whatever data type I like. Well that's the idea anyway......
6
by: Mikey_Doc | last post by:
Hi We are running cms 2002, Framework 1.0 with Visual studio 2002. We have just upgraded to Framework 1.1 and visual studio 2003. All of our database connection strings are stored within the...
0
by: Doug Gault | last post by:
I've been very pleased to find that you can load an XML file into a DATASET using the XMLREAD method, but I'm having a problem when trying to load a file that contains self-referencing elements. ...
10
by: rshepard | last post by:
While working with lists of tuples is probably very common, none of my five Python books or a Google search tell me how to refer to specific items in each tuple. I find references to sorting a list...
2
by: Mystagogue | last post by:
Is it possible for a single xpath expression, perhaps using back- referencing, to return the only the "item" elements having a "result" that matches the parent "foo result"? <foo result="false"...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.