Я бы хотел избежать цикла
У меня есть это:
string s = "AAAA,12,BBBB,34,CCCCC,56";
С Linq, я бы хотел иметь 2-й список
В первом: AAAA, BBBB и CCCCC
Во втором: 12,34 и 56
Он не основан на числовых или не числовых.
Спасибо,
Я бы хотел избежать цикла
У меня есть это:
string s = "AAAA,12,BBBB,34,CCCCC,56";
С Linq, я бы хотел иметь 2-й список
В первом: AAAA, BBBB и CCCCC
Во втором: 12,34 и 56
Он не основан на числовых или не числовых.
Спасибо,
Вы можете использовать
var str = "AAAA,12,BBBB,34,CCCCC,56";
var spl = str.Split(',');
var l1 = spl.Where((x, y) => y % 2 == 0).ToList();
var l2 = spl.Where((x, y) => y % 2 == 1).ToList();
Это проверит, является ли индекс четным или нечетным.
Использует Aggregate
для удовольствия от него (а также, чтобы доказать, что это можно сделать как одно выражение):
"AAAA,12,BBBB,34,CCCC,56".Split(',').Aggregate(
new { Uneven = new List<string>(), Even = new List<string>() },
(seed, s) => {
if (seed.Uneven.Count > seed.Even.Count)
seed.Even.Add(s);
else
seed.Uneven.Add(s);
return seed;
});
В соответствии с LINQPad результатом является следующее:
Конечно, я, вероятно, не сделал бы этого так, как его трудно читать. И тестирование, для которого список добавляется, - это, ну, не приятно.
Но, по крайней мере, у нас теперь есть еще один пример лямбда-операторов - обычно литература LINQ пытается забыть их (вероятно, потому, что они не будут работать с SQL или любым другим бэкэнд, который использует деревья выражений).
Одно из преимуществ этого метода, в отличие от вышеописанных чистых решений, состоит в том, что это только делает один проход через список. Так как мы раскалываем строку, я бы попытался оптимизировать где-то еще;) Не было бы IEnumerable<string> Split(this string self, string boundary)
быть круто?
Учитывая, что правило состоит в том, что вы хотите, чтобы каждая вторая строка в одном списке и другие в другом списке, вы можете сделать что-то вроде этого:
string s = "AAAA,12,BBBB,34,CCCCC,56";
var parts = s.Split(',');
var first = parts.Where((p, i) => i % 2 == 0);
var second = parts.Where((p, i) => i % 2 == 1);
Я точно не знаю, какова ваша конечная цель, но вы можете попробовать следующее:
var strings = s.Split(',').Where( (s,p) => p % 2 == 0)
Здесь есть хороший учебник http://msdn.microsoft.com/en-us/library/bb397915.aspx
Вот инемерный и не числовой фильтр для тех, кто заинтересован... я понимаю, что он не нужен
string x = "AAAA,12,BBBB,34,CCCCC,56";
Regex _isNumber = new Regex(@"^\d+$");
string[] y = x.Split(',') .Where(a => _isNumber.IsMatch(a)).ToArray();
string[] z =x.Split(',') .Where(a => !_isNumber.IsMatch(a)).ToArray();
вы можете группировать позицию и список, который вы перечисляете из группы, например:
public IEnumerable<IEnumerable<T>> ToLists<T>(IEnumerable<T> sequence)
{
var res = sequence.Select((item, position) => new { Item = item, Position = position })
.GroupBy(pair => pair.Position % 2 == 0,pair => pair.Item);
return from grouping in res
select grouping;
}
Если вы хотите, чтобы списки имели разные типы, вы можете перебирать результат. Поэтому возвращаемый тип не IEnumerable > , а IEnumerable > . использование ToList будет итерировать последовательность, но если вы хотите выполнить какое-либо действие над каждым элементом, вы можете также объединить эти действия, выполните одну итерацию через sequnce superflourious
Так весело, без побочных эффектов и без вызовов методов.
"TesteDessaBudega".Aggregate(new List<List<char>>(),
(l, c) => char.IsUpper(c) ?
l.Union(
new List<List<char>>(){
new List<char>(){c}
}
).ToList() :
l.Take(l.Count - 1).Union(
new List<List<char>>(){
l.Last().Union(
new List<char>(){c}
).ToList()
}
).ToList()
)
О, на vbnet просто для большего удовольствия.
"TesteDessaBudega".Aggregate(New List(Of List(Of Char))(),
Function(l, c) If(Char.IsUpper(c),
l.Union(
New List(Of List(Of Char))(New List(Of Char)(){
New List(Of Char)(New Char(){c})
})
).ToList(),
l.Take(l.Count - 1).Union(
New List(Of List(Of Char))(New List(Of Char)(){
l.Last().Union(
New List(Of Char)(New Char(){c})
).ToList()
})
).ToList()
))
Если список не упорядочен с каждой секундой, являющейся номером, вы можете сделать что-то вроде этого
var stringList = "AAAA,12,BBBB,34,CCCCC,56".Split(',');
var intsAsStrings = stringList.Where(
(x) =>
{
int i;
return int.TryParse(x, out i);
}).ToList();
var strings = stringList.Where(x => !intsAsStrings.Contains(x)).ToList();