m_a_n
asked on
How to divide a big C# SortedList into smaller SortedLists?
Hi,
I have to send out emails using a script. Exchange server has a limit of 25 emails (cannot change, its company policy).
My code is:
SendEmails (slAddresses[_key].ToStrin g());
I will appreciate if someone can please post code to divide the SortedList into multiple SortedLists (if the slAddresses has more than 25 records) and use same method multiple times to perform this.
Thanks in advance.
H
I have to send out emails using a script. Exchange server has a limit of 25 emails (cannot change, its company policy).
My code is:
SendEmails (slAddresses[_key].ToStrin
I will appreciate if someone can please post code to divide the SortedList into multiple SortedLists (if the slAddresses has more than 25 records) and use same method multiple times to perform this.
Thanks in advance.
H
P.S.
You would then process the resulting array as:
You would then process the resulting array as:
SortedList<string, string> slAddresses = new SortedList<string, string>();
SortedList<string, string>[] smallerLists = GetSmallerLists(slAddresses);
foreach (SortedList<string, string> list in smallerLists)
{
// Mail current list
foreach (string _key in list)
{
SendEmails(list[_key].ToString());
}
}
ASKER
Thanks there, unfortunately I get this error.
The non-generic type 'System.Collections.Sorted List' cannot be used with type arguments.
Any thoughts?
Really appreciated.
The non-generic type 'System.Collections.Sorted
Any thoughts?
Really appreciated.
ASKER
// The error is for this line:
public SortedList<string, string>[] GetSmallerLists(SortedList <string, string> sourceList)
public SortedList<string, string>[] GetSmallerLists(SortedList
Hi friend,
try this!
private void Form1_Load()
{
SortedList slAdresses = new SortedList();
for (int i = 1; i <= 100; i++)
{
slAdresses.Add(i.ToString( ), string.Format("Adress #{0}", i.ToString()));
}
foreach (SortedList lst in SplitList(slAdresses, 25))
{
//SendEmail(lst);
Console.WriteLine(lst.Coun t); //all lists have 25 in them..
}
}
private List> SplitList(SortedList SL, int Max)
{
if (SL.Count <= Max)
return new List>() { SL };
List> retVal = new List>();
SortedList tmpLst = new SortedList();
foreach (KeyValuePair kvp in SL)
{
tmpLst.Add(kvp.Key, kvp.Value);
if (tmpLst.Count > Max - 1)
{
retVal.Add(tmpLst);
tmpLst = new SortedList();
}
}
return retVal;
}
I think with that code you can get it to work your way!
bye!
try this!
private void Form1_Load()
{
SortedList slAdresses = new SortedList();
for (int i = 1; i <= 100; i++)
{
slAdresses.Add(i.ToString(
}
foreach (SortedList lst in SplitList(slAdresses, 25))
{
//SendEmail(lst);
Console.WriteLine(lst.Coun
}
}
private List> SplitList(SortedList SL, int Max)
{
if (SL.Count <= Max)
return new List>() { SL };
List> retVal = new List>();
SortedList tmpLst = new SortedList();
foreach (KeyValuePair kvp in SL)
{
tmpLst.Add(kvp.Key, kvp.Value);
if (tmpLst.Count > Max - 1)
{
retVal.Add(tmpLst);
tmpLst = new SortedList();
}
}
return retVal;
}
I think with that code you can get it to work your way!
bye!
ASKER
To: kaufmed
Thanks buddy I needed to have using System.Collections.Generic ; to not get any build errors.
I will test this code and let you know.
Thanks vanoch for your efforts as well.
Will come back soon!
Thanks buddy I needed to have using System.Collections.Generic
I will test this code and let you know.
Thanks vanoch for your efforts as well.
Will come back soon!
>> using System.Collections.Generic
That is absolutely correct. Sorry for not pointing it out. I sometimes forget that there are non-generic versions of most of the collections in .NET :)
That is absolutely correct. Sorry for not pointing it out. I sometimes forget that there are non-generic versions of most of the collections in .NET :)
ASKER
Thanks Kaufmed, I think we are very close:
Now the only error I get is:
"Cannot convert type 'System.Collections.Generi c.KeyValue Pair<strin g,string>' to 'string'"
As my SortedList is a non-generic version.
Any changes you would suggest?
Thanks a lot.
Now the only error I get is:
"Cannot convert type 'System.Collections.Generi
As my SortedList is a non-generic version.
Any changes you would suggest?
Thanks a lot.
Instead of actually splitting the list, why not just loop through it 25 items at a time (I used a List<string> in my example to hold all the addresses)?
class Program
{
static void Main(string[] args)
{
List<string> emails = new List<string>();
// Create a dummy list of e-mail addresses just for testing
for (int i = 0; i < 100; i++)
emails.Add("address" + i.ToString());
SendEmails(emails);
}
static void SendEmails(List<string> Addresses)
{
int groups = Addresses.Count / 25;
for (int i = 0; i < groups; i++)
{
MailMessage message = new MailMessage();
for (int j = 0; j < 25; j++)
{
message.To.Add(Addresses[i + j]);
}
smtp.Send(message);
}
}
}
Oops, I made a boo-boo! Line 23 should read:
message.To.Add(Addresses[j + (i * 25)]);
message.To.Add(Addresses[j
I'm not as clever as I thought. ;)
You also need to account for instances when the list isn't evenly divisible my the number of addresses, i.e. with 26 addresses divided by 25 = 1, but you need two messages for the 26th address.
I just wrote string to console for testing, but you get the idea!
You also need to account for instances when the list isn't evenly divisible my the number of addresses, i.e. with 26 addresses divided by 25 = 1, but you need two messages for the 26th address.
I just wrote string to console for testing, but you get the idea!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Mail;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<string> emails = new List<string>();
// Create a dummy list of e-mail addresses just for testing
for (int i = 0; i < 16; i++)
emails.Add("address" + i.ToString());
SendEmails(emails, 5);
Console.ReadKey();
}
static void SendEmails(List<string> Addresses, int maxPerMessage)
{
int groups = Addresses.Count / maxPerMessage;
int remainder = Addresses.Count % maxPerMessage;
for (int i = 0; i < groups; i++)
{
Console.WriteLine("\r\n\r\nStarting new message...");
for (int j = 0; j < maxPerMessage; j++)
{
Console.WriteLine(Addresses[j + (i * maxPerMessage)]);
}
}
if (remainder > 0)
{
Console.WriteLine("Last message...");
for (int i = 0; i < remainder; i++)
{
Console.WriteLine(Addresses[(groups * maxPerMessage) + i]);
}
}
}
}
}
Converted to non-generic form:
public SortedList[] GetSmallerLists(SortedList sourceList)
{
const int MAX_SIZE = 25;
SortedList[] smallerLists = new SortedList[(sourceList.Count % MAX_SIZE) + 1];
int i;
int j = 0;
for (i = 0; i < smallerLists.Length; i++) smallerLists[i] = new SortedList(MAX_SIZE);
i = 0;
foreach (string key in sourceList.Keys)
{
smallerLists[j].Add(key, sourceList[key]);
i++;
if (i == MAX_SIZE)
{
j++;
i = 0;
}
}
return smallerLists;
}
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
Haha...I was just about to call you on that. ;)
Was going to suggest:
SortedList[] smallerLists = new SortedList[sourceList.Coun t / MAX_SIZE + (sourceList.Count % MAX_SIZE == 0 ? 0 : 1)];
Was going to suggest:
SortedList[] smallerLists = new SortedList[sourceList.Coun
>> Haha...I was just about to call you on that. ;
Good thing I'm quick ;)
In my example, MAX_SIZE is a const value, as opposed to your parameterized version, so that would be irrelevant for mine--unless someone was crazy enough to make zero the const value!
Good thing I'm quick ;)
In my example, MAX_SIZE is a const value, as opposed to your parameterized version, so that would be irrelevant for mine--unless someone was crazy enough to make zero the const value!
ASKER
Thanks a lot Kafumed. It was just perfect.
Others' efforts would have been good as well, though I did not try them.
Thanks all of you.
Others' efforts would have been good as well, though I did not try them.
Thanks all of you.
NP. Glad to help :)
Open in new window