0

I am using following code to create an array to find out start and end index of a multidimensional array:

var valueArray = Enumerable.Range(0, val.GetLength(1))
                                     .Where(index => val[0, index].Contains("Rak"))
                                     .ToArray();

Than i am using valueArray to get start index which is valueArray[0] and end index which will be valueArray[valueArray.Length-1].

Above code works. But it looks like it is doing aweful amout of work to get start and end index. As it is first creating valueArray putting in all values in it and then getting index values. Can anyone suggest better way of doing this?

Defination of array:

private string[,] _val;
 public string[,] val
        {
            [Pure]
            get
            {
                if (_val != null)
                    return (string[,])_val.Clone();
                return null;
            }
            set
            {
                _val = value;
            }
        }
15
  • I don't see anything wrong with your implementation. Is speed/efficiency that much of a factor for what you are trying to accomplish? Commented Oct 4, 2013 at 19:14
  • @Brian - Yes speed is an issue if i have to go through array of lets say 6k rows its taking very long time. Commented Oct 4, 2013 at 19:16
  • I would think another strategy, can't you create an index? Or a List of Lists? Commented Oct 4, 2013 at 19:17
  • @JeroenvanLangen - create an index? That is what i am doing right? Any other way? Commented Oct 4, 2013 at 19:18
  • What does the array contains? [int,string]? I would define it like Dictionary<int, HashSet<string>> This way you can call directly val[i].Contains("Rak"); Commented Oct 4, 2013 at 19:19

2 Answers 2

1

I'd rather would go for something like this:

public class CellInfo
{
    public int Row { get; set; }
    public int Column { get; set; }
    public string Value { get; set; }
}

Example:

List<CellInfo> _cells = new List<CellInfo>();

public void Example()
{
    _cells.Add(new CellInfo { Column = 6, Row = 3, Value = "Rak" });
    _cells.Add(new CellInfo { Column = 3, Row = 8, Value = "Rak" });
    _cells.Add(new CellInfo { Column = 2, Row = 4, Value = "Rak" });
    _cells.Add(new CellInfo { Column = 5, Row = 7, Value = "Sac" });
    _cells.Add(new CellInfo { Column = 1, Row = 3, Value = "Sac" });

    int[] rowRakAtColumn0 = _cells.Where(cell => cell.Column == 0
                                        && cell.Value.Contains("Rak"))
                                            .OrderBy(cell => cell.Row)
                                                .Select(cell => cell.Row)
                                                    .ToArray();

    CellInfo[] row0Values = _cells.Where(cell => cell.Row == 0)
                                .OrderBy(cell => cell.Column)
                                    .ToArray();
}

Converting it to a multi array (if needed)

public string[,] ToMultiArray(List<CellOffset> cells)
{
    string[,] multiDimentional = new string[
        cells.Max(cell => cell.Column), cells.Max(cell => cell.Row)];

    cells.ForEach(cell => 
        multiDimentional[cell.Column, cell.Row] = cell.Value);

    return multiDimentional;
}

string[,] values = ToMultiArray(_cells);

Answer to lazzy_ms:

The linq .Select() method is also able to pass the index as second parameter for your lambda function. You only need to capture it in an anonymous class.

var result = _cells
    //             here         and capture it in an object
    //              |
    .Select((Item, Index) => new { Item, Index })
    .FirstOrDefault(itemWithIndex => itemWithIndex.Item.Column == 5);

Console.WriteLine($"The index of column 5 is {result?.Index}");

Make sure you select the index before any filtering takes place. else it wont match

Sign up to request clarification or add additional context in comments.

3 Comments

Hey, I made a class for data, same way. I just want the index of an item containing name = "customer1".
@lazzy_ms you mean the Column and Row?
Yes, in this example, I want the index of column = 5. That would be 3
0

One way to optimize the code is to search first and last elements from the begining and from the end respectively.

int firstIndex;
int lastIndex; 
for(int i = 0; i < val.GetLength(1); i++)
{
    if(val[0,i].Contains("Rak"))
    {
        firstIndex = i;
        break;
    } 
}
for(int i = val.GetLength(1) - 1; i>=0; i--)
{
    if(val[0,i].Contains("Rak"))
    {
        lastIndex = i;
        break;
    } 
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.