Попробуйте использовать
int your_number = 20;
String url = "http://itunes.apple.com/us/rss/topsongs/limit=20/genre=29/explicit=true/json;"
url = url.replace("genre=29", "genre"+your_number);
и теперь используйте URL для запроса.
Вы можете свернуть собственный экземпляр ZipMany, который вручную выполняет итерацию каждого из перечислений. Вероятно, это будет лучше для больших последовательностей, чем те, которые используют GroupBy
после проецирования каждой последовательности:
public static IEnumerable<TResult> ZipMany<TSource, TResult>(
IEnumerable<IEnumerable<TSource>> source,
Func<IEnumerable<TSource>, TResult> selector)
{
// ToList is necessary to avoid deferred execution
var enumerators = source.Select(seq => seq.GetEnumerator()).ToList();
try
{
while (true)
{
foreach (var e in enumerators)
{
bool b = e.MoveNext();
if (!b) yield break;
}
// Again, ToList (or ToArray) is necessary to avoid deferred execution
yield return selector(enumerators.Select(e => e.Current).ToList());
}
}
finally
{
foreach (var e in enumerators)
e.Dispose();
}
}
Взгляните на проект linqlib на codeplex , он имеет функцию поворота, которая делает именно то, что вам нужно.
Вот неэффективный вариант, основанный на трансформации матрицы:
public static class Ext
{
public static IEnumerable<IEnumerable<T>> Rotate<T>(
this IEnumerable<IEnumerable<T>> src)
{
var matrix = src.Select(subset => subset.ToArray()).ToArray();
var height = matrix.Length;
var width = matrix.Max(arr => arr.Length);
T[][] transpose = Enumerable
.Range(0, width)
.Select(_ => new T[height]).ToArray();
for(int i=0; i<height; i++)
{
for(int j=0; j<width; j++)
{
transpose[j][i] = matrix[i][j];
}
}
return transpose;
}
}
(from count in Range(myList[0].Count)
select new List<string>(
from count2 in Range(myList.Count)
select myList[count2][count])
).ToList();
Это не очень, но я думаю, что это сработает.
mylist
есть три списка. Я надеялся больше на решение, которое работает независимо от количества списков.
– Michael0x2a
31 July 2013 в 18:36
Вы можете конденсировать петли for
, используя Диапазон :
var result = Enumerable.Range(0, myList.Min(l => l.Count))
.Select(i => myList.Select(l => l[i]).ToList()).ToList();
Вы можете сделать это, используя расширение Select
с помощью Func<T, int, TOut>
:
var rotatedList = myList.Select(inner => inner.Select((s, i) => new {s, i}))
.SelectMany(a => a)
.GroupBy(a => a.i, a => a.s)
.Select(a => a.ToList()).ToList();
. Это даст вам еще один List<List<string>>
.
Breakdown
.Select(inner => inner.Select((s, i) => new {s, i}))
Для каждого внутреннего списка мы проецируем содержимое списка на новый анонимный объект с двумя свойствами: s
, строковое значение и i
индекс этого значения в исходном списке.
.SelectMany(a => a)
Мы сглаживаем результат до одного списка
.GroupBy(a => a.i, a => a.s)
. Мы группируем по свойству i
нашего анонимного объекта (напомним, что это индекс) и выберите s
как наши значения (только строка).
.Select(a => a.ToList()).ToList();
Для каждой группы мы изменили перечисление на список и еще один список для всех групп.
Как насчет использования SelectMany
и GroupBy
с некоторыми индексами?
// 1. Project inner lists to a single list (SelectMany)
// 2. Use "GroupBy" to aggregate the item's based on order in the lists
// 3. Strip away any ordering key in the final answer
var query = myList.SelectMany(
xl => xl.Select((vv,ii) => new { Idx = ii, Value = vv }))
.GroupBy(xx => xx.Idx)
.OrderBy(gg => gg.Key)
.Select(gg => gg.Select(xx => xx.Value));
Из LinqPad:
[/g0]
IEnumerable<IEnumerable<T>>
).
– Simon Belanger
31 July 2013 в 18:39