0

I have a List of Lat/Lon co-ordinates that I'm processing in a while(true) loop. During the loop I'm building a query that will be sent to a remote service for processing. The remote service can only accept 12 pairs of Lat/Lon co-ordinates, however my list may contain several thousand. What I want to do is build the query and then send it for processing every 12 loops.

List<string[]> lList = FromDB();

int i = 0;
int intLastIndex - lList.Count;
string strQuery = String.Empty

while(true)
{
    strQuery = lList[i][0] + "|" + lList[i][1];

    if(((i % 11) == 0) && (i != 0))
    {
        SendToRemoteService(strQuery);
        strQuery = String.Empty;
    }

    if(i == intLastIndex)
    {
        break;
    }

    i++
}

However this generate an array out of bounds exception and will not process all records. Can anyone suggest a better approach?

Mark

3 Answers 3

8

I have found at least 5 bugs in your code, you should rewrite it to:

List<string[]> lList = FromDB();
List<string> query = new List<string>();
for(int i = 0; i < lList.Count; i++)
{
    query.Add(lList[i][0] + "|" + lList[i][1]);

    if((((i + 1) % 12) == 0) || (i == (lList.Count - 1)))
    {
        SendToRemoteService(String.Join("|", query.ToArray()));
        query.Clear();
    }
}

But if you want to upgrade to C# 3.0 you can use System.Linq, aka Linq-to-objects, which will simplify your code. Imagine you would want to send a single pair per request, then your code would be:

List<string[]> lList = FromDB();
var queries = lList
    .Select(latlon => String.Format("{0}|{1}", latlon[0], latlon[1]));
foreach(var query in queries)
{
    SendToRemoteService(query);
}

Now grouping into groups of 12 pairs:

List<string[]> lList = FromDB();
var queries = lList
    .Select((latlon, index) => new { latlon, index })
    .GroupBy(item => item.index / 12, item => item.latlon)
    .Select(group => String.Join("|", 
         group.Select(latlon =>  String.Format("{0}|{1}", latlon[0], latlon[1]))
              .ToArray()
     ));
foreach(var query in queries)
{
    SendToRemoteService(query);
}

code style note: many people would rather use query instead of strQuery as a variable name.

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

4 Comments

We should use TDD for this =)
By using the GroupBy statement you are going to have all the data in memory (take care of your memory;))
List<string[]> lList = FromDB(); don't mind my comment, everything is already in memory...
Jader, Thanks for your response - I was having a tough time getting the problem straight in my mind. The Linq solution is very cool.
3

You also need a final "SendToRemoteService" call after the loop if the strQuery is not empty after the exit.

1 Comment

Nice answer. I was thinking of trying a linq solution, but I'm still too green at it.
3

The Count function will return the total number of items in your list while the [] accessor starts at 0 so your list will work if you make the following change

int intLastIndex - lList.Count;

To

int intLastIndex =  lList.Count == 0 ? 0 : lList.Count-1;

2 Comments

your correction alone won't prevent an exception when the length is 0
the problem isn't the line, the problem is the while(true) thing, it has to be replaced by a while(i < intLastIndex) or a for at least

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.