Требуется фанки LINQ - PullRequest
       2

Требуется фанки LINQ

1 голос
/ 03 ноября 2011

Ниже приведена строка CSV, с которой я работаю.В реальности это намного больше, но этого достаточно, чтобы отобразить шаблон.

Обратите внимание, что я поместил этот CSV на отдельные линии, чтобы просто продемонстрировать свой паттерн.

После разделения CSV количество полей меняется в зависимостио том, насколько велика исходная строка, т. е. строка переменной длины, что делает число индексов переменным

Буква в шаблоне не всегда может быть P, это может быть U, Oили F

G9999999990001800002777107050,
G9999999990002777107HMNLAQKPRLLHRAQRWJ010,
1,
3,
29,
P,
6.74,
11.23,
07,
U,
5.25,
14.29,
08,
O,
6.89,
16.92,
07,
P,
5,
4,

Я хочу взять 5-й (29) и 6-й (P) элементы, а затем пропустить 2 элемента, а затем выбрать следующий элемент (07) и один после (P) и так до тех пор, пока я не доберусь до конца строки.

В этом примере у меня будет 29 P 07 P 08 P 07 P

Есть ли простой способ сделать это, яПредположим, что LINQ предложит что-нибудь

Спасибо

Ответы [ 5 ]

4 голосов
/ 03 ноября 2011
line.Split(',')  //split on commas as it seems from your question that's your input
    .Skip(2) //skip the first two entries
    .Where((l, i) => i % 4 == 3 || i % 4 == 0) //take every 3rd and 4th item
    .Skip(1); //skip the first item since the index is divisible by 4

Но это совсем не похоже на описание того, что делает код, я бы хотя бы оставил комментарий.

2 голосов
/ 03 ноября 2011

Полная демонстрация по http://ideone.com/EDof0

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

public class Program
{
    public static IEnumerable<int> SpecialIndexes()
    {
        int i=4; 

        while (i<Int32.MaxValue)
        {
            yield return i++;
            yield return i++;
            i += 2;
        }
    }

    public static void Main(string[] args)
    {
        var csvString = "G9999999990001800002777107050,G9999999990002777107HMNLAQKPRLLHRAQRWJ010,1,3,29,P,6.74,11.23,07,P,5.25,14.29,08,P,6.89,16.92,07,P,5,4,";

        var fields = csvString.Split(',');
        var selected = SpecialIndexes()
            .TakeWhile(i => i<fields.Length)
            .Select(i => fields[i]);

        Console.WriteLine(string.Join(" ", selected.ToArray()));
    }
}

Выход:

29 P 07 P 08 P 07 P

0 голосов
/ 05 ноября 2011

Для разбора строки я бы использовал RegEx вместо Linq, так как он компилируется и намного быстрее.

0 голосов
/ 03 ноября 2011
string[] thestrings = source.Split(',');
string lastItem = thestrings.FirstOrDefault();
List<string> keepers = new List<string>();

foreach(string item in thestrings)
{
  if (item == "P")
  {
    if (lastItem != "P")
    {
      keepers.Add(lastItem);
    }
    keepers.Add(item);
  }
  lastItem = item;
}
0 голосов
/ 03 ноября 2011

я сделал что-то подобное вчера ... вот мой код

//Create a new variable of string
var x = string.Empty;
//Open a new FileStream
using (var fs = new FileStream(path,...))
//Open the StreamReader
using (var sr = new StreamReader(fs))
{
//Read out the whole CSV
   x = sr.ReadToEnd();
}

//Split up the string by ',' and whitespaces. dismiss empty entries
var stringArray = x.Split(new char[] { ',', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)

//stolen code following 
var myEnumerable = stringArray.Skip(2)
                              .Where((item, index) => index % 4 == 3 || index % 4 == 0)
                              .Skip(1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...