C#:将字符串数组分成N个实例的最简洁方法N个项目长

时间:2009-06-17 18:28:45

标签: c# arrays string loops

我知道如何以丑陋的方式做到这一点,但我想知道是否有更优雅和简洁的方法。

我有一个字符串数组的电子邮件地址。假设字符串数组具有任意长度 - 它可能有几个项目,或者它可能有很多项目。我想构建另一个字符串,包括来自字符串数组的50个电子邮件地址,直到数组的末尾,并在每个50之后使用Send()方法中的50个地址的字符串调用发送操作。

更普遍的问题是,做这种事情的最干净/最清晰的方法是什么。我有一个解决方案,这是我的VBScript学习的遗产,但我认为在C#中有更好的方法。

7 个答案:

答案 0 :(得分:49)

你想要优雅和简洁,我会给你优雅和简洁:

var fifties = from index in Enumerable.Range(0, addresses.Length) 
              group addresses[index] by index/50;
foreach(var fifty in fifties)
    Send(string.Join(";", fifty.ToArray());

为什么不必使用所有可怕的循环代码?你想要把事情按五十年代分组,然后把它们分组五十年代。 这就是集团运营商的目标!

更新:评论者MoreCoffee询问这是如何工作的。我们假设我们想按三分组,因为这更容易输入。

var threes = from index in Enumerable.Range(0, addresses.Length) 
              group addresses[index] by index/3;

我们假设有9个地址,索引为0到8

这个查询是什么意思?

Enumerable.Range是从零开始的九个数字的范围,因此0, 1, 2, 3, 4, 5, 6, 7, 8

范围变量index依次获取每个值。

然后我们检查每个相应的addresses[index]并将其分配给一个组。

我们将哪个组分配给它?要对index/3进行分组。整数运算在C#中向零舍入,因此当除以3时,索引0,1和2变为0。当除以3时,索引3,4,5变为1.索引6,7,8变为2.

因此,我们将addresses[0]addresses[1]addresses[2]分配到第0组,addresses[3]addresses[4]addresses[5]到第1组,等等上。

查询结果是三个组的序列,每个组是三个项目的序列。

这有意义吗?

还要记住,查询表达式的结果是一个表示此操作的查询。在执行foreach循环之前,它不会执行操作。

答案 1 :(得分:14)

似乎与此问题类似:Split a collection into n parts with LINQ?

Hasan Khan 的修改版本的答案应该可以解决问题:

public static IEnumerable<IEnumerable<T>> Chunk<T>(
    this IEnumerable<T> list, int chunkSize)
{
    int i = 0;
    var chunks = from name in list
                 group name by i++ / chunkSize into part
                 select part.AsEnumerable();
    return chunks;
}

用法示例:

var addresses = new[] { "a@example.com", "b@example.org", ...... };

foreach (var chunk in Chunk(addresses, 50))
{
    SendEmail(chunk.ToArray(), "Buy V14gr4");
}

答案 2 :(得分:2)

听起来输入包含大型数组中的单独电子邮件地址字符串,而不是一个字符串中的多个电子邮件地址,对吧?在输出中,每个批次都是一个组合字符串。

string[] allAddresses = GetLongArrayOfAddresses();

const int batchSize = 50;

for (int n = 0; n < allAddresses.Length; n += batchSize)
{
    string batch = string.Join(";", allAddresses, n, 
                      Math.Min(batchSize, allAddresses.Length - n));

    // use batch somehow
}

答案 3 :(得分:2)

假设您使用的是.NET 3.5和C#3,那么这样的事情应该很好用:

string[] s = new string[] {"1", "2", "3", "4"....};

for (int i = 0; i < s.Count(); i = i + 50)
{
    string s = string.Join(";", s.Skip(i).Take(50).ToArray());
    DoSomething(s);
}

答案 4 :(得分:1)

我只是循环遍历数组并使用StringBuilder来创建列表(我假设它是分开的;就像你对电子邮件一样)。只需在你点击mod 50或结束时发送。

void Foo(string[] addresses)
{
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < addresses.Length; i++)
    {
        sb.Append(addresses[i]);
        if ((i + 1) % 50 == 0 || i == addresses.Length - 1)
        {
            Send(sb.ToString());
            sb = new StringBuilder();
        }
        else
        {
            sb.Append("; ");
        }
    }
}

void Send(string addresses)
{
}

答案 5 :(得分:0)

我认为我们需要更多地了解这个列表究竟是什么样的,以给出明确的答案。现在我假设这是一个以分号分隔的电子邮件地址列表。如果是这样,您可以执行以下操作以获取分块列表。

public IEnumerable<string> DivideEmailList(string list) {
  var last = 0;
  var cur = list.IndexOf(';');
  while ( cur >= 0 ) {
    yield return list.SubString(last, cur-last);
    last = cur + 1;
    cur = list.IndexOf(';', last);
  }
}

public IEnumerable<List<string>> ChunkEmails(string list) {
  using ( var e = DivideEmailList(list).GetEnumerator() ) {
     var list = new List<string>();
     while ( e.MoveNext() ) {
       list.Add(e.Current);
       if ( list.Count == 50 ) {
         yield return list;
         list = new List<string>();
       }
     }
     if ( list.Count != 0 ) {
       yield return list;
     }
  }
}

答案 6 :(得分:0)

我认为这很简单,也很快。下面的示例将长句分为15个部分,但您可以将批量大小作为参数传递给动态。这里我只是用“/ n”来划分。

 private static string Concatenated(string longsentence)
 {
     const int batchSize = 15;
     string concatanated = "";
     int chanks = longsentence.Length / batchSize;
     int currentIndex = 0;
     while (chanks > 0)
     {
         var sub = longsentence.Substring(currentIndex, batchSize);
         concatanated += sub + "/n";
         chanks -= 1;
         currentIndex += batchSize;
     }
     if (currentIndex < longsentence.Length)
     {
         int start = currentIndex;
         var finalsub = longsentence.Substring(start);
         concatanated += finalsub;
     }
     return concatanated;
 }

显示拆分操作的结果。

 var parts = Concatenated(longsentence).Split(new string[] { "/n" }, StringSplitOptions.None);