0

I am wanting to efficiently convert a multidimensional object array into a list of joined arrays.

Firstly, I have converted the 2D array into a list of arrays:

object[,] data; // This contains all the data.
int count = 0;
List<string[]> dataList = data.Cast<string>()
                          .GroupBy(x => count++ / data.GetLength(1))
                          .Select(g => g.ToArray())
                          .ToList();

And now what I want to do is create a List where I trim and then join all the data in each array. To clarify what I mean, I can do this using:

List<string> dataListCombined = new List<string>();
foreach (string[] s in dataList)
{
    for (int i = 0; i < s.Length; i++)
    {
        s[i] = s[i].Trim();
    }
    dataListCombined.Add(string.Join(",", s));
}

but i just want to know if there is a more efficient way of doing it. Can I alter LINQ Im using above to do it? Thanks

4
  • 1
    Any chance you can show us a sample of the data? It would be helpful, for example, if we could see the data (and the format it's in) along with what you want the data to ultimately look like. Commented Sep 18, 2019 at 13:49
  • 1
    In addition to my comment above, I'm also wondering why, in your first code sample, you don't convert data to a List<List<string>> instead of a List<string[]>. In general, lists are so much easier to work with than arrays. Commented Sep 18, 2019 at 13:52
  • 2
    Bad idea to put a side-effect into a LINQ predicate. The correct functional programming way is to use a form of select with a predicate that takes an index, and use the index to group - which may also require creating an anonymous object that includes both the index and the original data. It's a bit more work to set up, but this is how predicates are supposed to work as pure functions. I believe side effects in LINQ predicates constitute undefined behaviour. (See the technique in @RashidAli's answer) Commented Sep 18, 2019 at 14:35
  • 1
    This is not an efficient way to return array rows to begin with and using such side effects is a very bad idea - why group data when you already know how to access it? Instead of direct access you pay for the division operations, hashing, storing the group data in internal lists and emitting it to the next step. All those string operations generate temporary objects that have to be GC'd adding another layer of inefficiency. Commented Sep 18, 2019 at 15:11

2 Answers 2

1

Following LINQ code will produce the same results as your complete code in both blocks:

This code will work for a multi dimensional array of any rank (dimensions)

//dimensions in the array
int arrayDimensions = data.Rank;

//create a group of items in each row of the array
//join all items of each group into a comma separated string
//combine all formed strings into a list of strings

List<string> dataListCombined = 
data.Cast<string>().Select((s, i) => new { GroupIndex = i / arrayDimensions, Item = s.Trim()}).
GroupBy(g => g.GroupIndex).Select(g => string.Join(",", g.Select(x => x.Item))).ToList();
Sign up to request clarification or add additional context in comments.

2 Comments

You forgot to assign Item = s, and since OP seems interested in Trimming the data make it s.Trim()
Thanks. This is the answer but I had to update int arrayDimensions = data.Rank; to int arrayDimensions = data.GetLength(1);
0

A trick you can use with LINQ when accessing indexed values is simulating for loops with Enumerable.Range. This isn't more efficient, or even clearer, but does allow for code that indexes easily:

var dataCombined = Enumerable.Range(0, data.GetLength(0))
                             .Select(ri => String.Join(",", Enumerable.Range(0, data.GetLength(1))
                                                                      .Select(ci => data[ri,ci].ToString()
                                                                                               .Trim())))
                             .ToList();

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.