2013-11-12 4 views
1

У меня есть массив, который содержит 10000 значений, и я хочу взять каждое 50 элементов из массива и выполнить некоторые строковые операции. Как это сделать, используя цикл LINQ или FOR. Спасибо заранее.Строковые массивы в LINQ

+1

Взгляните на этот ответ (http://stackoverflow.com/a/3210961/259679). –

+0

Мне понравились некоторые из решений здесь, особенно тот, где он разбивает его на группы по 4 (или 50 в вашем случае), а затем работает с каждой группой. Обратите внимание, что вам не нужно иметь несколько элементов в массиве. http://stackoverflow.com/questions/9718117/selecting-first-10-records-then-next-10-paging-using-linq – MxyL

ответ

2

Вы можете использовать Skip и Take в вашем for цикле, как это:

for (int pos = 0 ; pos < values.Length ; pos += 50) { 
    var subArray = values.Skip(pos).Take(50).ToArray(); 
} 

Примечание: это было бы крайне неэффективно, если values не является массивом или List<String>.

Однако, это не самый эффективный способ сделать это: вы бы лучше не использовать LINQ вообще, и использовать Array.Copy метод вместо:

var subArray = new String[50]; 
for (int pos = 0 ; pos < values.Length ; pos += 50) { 
    Array.Copy(values, pos, subArray, 0, 50); 
} 

выше решение требует, чтобы subArray не хранится как часть любой обработки, которую вы планируете делать, и что values.Length будет делиться на 50 (с 10000 наименованиями, это так).

+1

Когда ввод не является «IList», это довольно ужасно неэффективно, но данный что 'Skip' имеет оптимизацию для' IList', с которой реализуются массивы, это действительно неплохо, производительность разумная. Конечно, если вы можете избежать превращения 'subArray' в массив и вместо этого просто использовать его как последовательность, это немного улучшит его. – Servy

+0

@Servy Спасибо, я добавил примечание, чтобы упомянуть эту потенциальную неэффективность. – dasblinkenlight

0

Сделать что, как list<string>

List <string> lst = array.ToList(); 

string [] strarr= lst.GetRange (0,50); 

От MSDN

0

Здесь вы идете:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     const int chunkSize = 50; 
     static void Main(string[] args) 
     { 
      var bigList = Enumerable.Range(0, 10000).Select(s => s.ToString()).ToList(); 

      ChunkerProcess(bigList, i => { Console.WriteLine(i); }); 
     } 

     private static void ChunkerProcess<T>(List<T> bigList, Action<T> action) 
     { 
      int pointer = 0; 
      List<T> chunks = bigList.GetRange(0, chunkSize>bigList.Count?bigList.Count:chunkSize); 
      while (chunks.Count > 0) 
      { 
       foreach (var chunk in chunks) 
       { 
        action.Invoke(chunk); 
       } 
       chunks.Clear(); 
       if (chunkSize * pointer < bigList.Count) 
       { 
        chunks = bigList.GetRange(chunkSize * pointer, chunkSize * (pointer + 1) > bigList.Count ? bigList.Count - chunkSize * pointer : chunkSize); 
        pointer++; 
       } 
      } 
     } 
    } 
} 
1

Вы можете просто использовать GetRange

 List<string> elements = yourArray.ToList(); 
     if (null != elements && elements.Count > 50) 
     { 
      for (int i = 0; i < elements.Count; i += 50) 
      { 
       Array result = elements.GetRange(i,50).ToArray(); 
       // here you can pass the retrived list to your private method to do the necessary functionility. 
       StringOperationForArray(result); 
      } 
     } 
+0

Пожалуйста, предоставьте мне приведенный выше код на vb.net – user2982630

+0

Если элементы.Count> 50 Then Для i As Integer = 0 К элементам. Шаг шага i + 50 Dim result As List (Of String) = elements.GetRange (i, 50) 'здесь вы можете передать извлеченный список вашему приватному методу для выполнения необходимой функциональности. StringOperationForList (результат) Следующая End If Я попытался, как приведенный выше код, но я получаю следующее сообщение об ошибке .. смещение и длина были вне границ для массива или количество больше, чем число элементов из индекса до конца коллекции источников. Спасибо за вашу помощь – user2982630

0

Если вы можете использовать Rx Extensions, это было бы моим любимым решением.

namespace ConsoleApplication2 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Reactive.Linq; 

    internal class Program 
    { 
     #region Constants 

     private const int chunkSize = 50; 

     #endregion 

     #region Methods 

     private static void Main(string[] args) 
     { 
      List<string> bigList = Enumerable.Range(0, 99).Select(s => s.ToString()).ToList(); 
      bigList.ToObservable().Buffer(chunkSize).Subscribe(
       chunk => 
       { 
        foreach (string s in chunk) 
        { 
         Console.WriteLine(s); 
        } 
        Console.WriteLine(String.Empty.PadRight(80, '-')); 
       }); 
     } 

     #endregion 
    } 
} 

В сочетании с Parallel Extensions Дополнительно

namespace ConsoleApplication2 
{ 
    using System; 
    using System.Collections.Concurrent; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Reactive.Linq; 
    using System.Threading; 
    using System.Threading.Tasks; 
    using System.Threading.Tasks.Schedulers; 

    internal class Program 
    { 
     #region Constants 

     private const int ChunkSize = 50; 

     #endregion 

     #region Methods 

     private static void Main(string[] args) 
     { 
      var cancellationTokenSource = new CancellationTokenSource(); 
      CancellationToken cancellationToken = cancellationTokenSource.Token; 
      var workStealingTaskScheduler = new WorkStealingTaskScheduler(Environment.ProcessorCount - 1); 
      var bag = new ConcurrentBag<Task>(); 
      IEnumerable<string> bigList = Enumerable.Range(0, 10000).Select(s => s.ToString()); 
      bigList.ToObservable().Buffer(ChunkSize).Subscribe(
       chunk => bag.Add(
        Task.Factory.StartNew(
         () => 
         { 
          foreach (string s in chunk) 
          { 
           Console.WriteLine(s); 
          } 
          Console.WriteLine(String.Empty.PadRight(80, '-')); 
         }, 
         cancellationToken, 
         TaskCreationOptions.None, 
         workStealingTaskScheduler))); 
      Task.WaitAll(bag.ToArray()); 
     } 

     #endregion 
    } 
} 
0

Как данные перечислены на самом деле? Если это IEnumerable, тогда даже foreach будет работать в порядке, если у вас есть List, тогда даже foreach или IEnumerable.ForEach также применим, и нет никаких дополнительных штрафных санкций в производительности даже путем резки данных. , например.

foreach(var item in list) 
{ 
//your operation here 
} 

ИЛИ

list.ForEach(o=> 
{ 
//your operation here 
} 
); 
Смежные вопросы