我有一个列的集合和一个整数的宽度集合,我想应用于它们。如何使它们彼此的大小独立?
假设我有列[col1, col2, col3, col4, col5]
和宽度[10,15,20]
结果应该是
col1: 10
col2: 15
col3: 20
col4: 10
col5: 15
对于[col1, col2]
和[10,15,20]
col1: 10
col2: 15
我之前通过操作自定义类型列表中的索引(如 if (i == widths.Length()) {i=0}
(手动做了类似的事情,但是系统类型或方法中是否有自动处理循环循环的内容?
你可以使用 modus
public static void CombineList()
{
List<string> cols = new List<string> {"col1", "col2", "col3", "col4", "col5", "col6", "col7"};
List<string> nums = new List<string> { "10", "20", "50"};
int numsCount = nums.Count;
List<string> comb = new List<string>();
for(int i = 0; i < cols.Count; i++)
{
string s = $"{cols[i]}: {nums[i%numsCount]}";
Debug.WriteLine(s);
comb.Add(s);
}
Debug.WriteLine("done");
}
col1: 10
col2: 20
col3: 50
col4: 10
col5: 20
col6: 50
col7: 10
如果您的集合已编制索引(例如使用 ArrayList(,那么您只需对列和权重集合使用模算术。要分配的权重类似于
列权重 = 权重[ 列索引 % # 权重]
您可以使用这样的函数,该函数将集合作为输入并返回它,以便重复其值,直到达到最小长度。
public static IEnumerable<T> RepeatToMinimumLength<T>(IEnumerable<T> input,
int minimumLength)
{
var inputAsList = input as List<T> ?? input.ToList();
if (inputAsList.Count >= minimumLength)
return inputAsList.Take(minimumLength);
if (!inputAsList.Any())
throw new ArgumentException("input must have at least one element.");
var output = new List<T>(inputAsList);
while(output.Count < minimumLength)
output.AddRange(inputAsList);
return output.Take(minimumLength);
}
您可以创建一个列表扩展来很好地处理它。称其为Expand
方法或其他方法。请注意,它会修改原始数据,因此模%
方法或创建返回新集合的方法总体上更安全。
public static class SomeListExtensions
{
public static void Expand<T>( this List<T> list, int count )
{
if ( count < list.Count )
{
list.RemoveRange( count, list.Count - count );
}
else if ( count > list.Count )
{
int oldCount = list.Count;
for ( int i = oldCount; i < count; i++ )
list.Add( list[ i % oldCount ] );
}
}
}
以下代码返回10, 15, 20, 10, 15
:
class Program
{
static void Main( string[] args )
{
List<int> values = new List<int>();
values.Add( 10 );
values.Add( 15 );
values.Add( 20 );
List<string> groups = new List<string>();
groups.Add( "col1" );
groups.Add( "col2" );
groups.Add( "col3" );
groups.Add( "col4" );
groups.Add( "col5" );
values.Expand( groups.Count );
Console.WriteLine( string.Join( ", ", values ) );
}
}
您要求对Enumerable.Zip
进行专门的实现:
public static IEnumerable<TResult> ZipCycle<TSource1, TSource2, TResult>(
this IEnumerable<TSource1> first,
IEnumerable<TSource2> second,
Func<TSource1, TSource2, TResult> selector)
{
if (first == null)
throw new ArgumentNullException(nameof(first));
if (second == null)
throw new ArgumentNullException(nameof(second));
if (selector == null)
throw new ArgumentNullException(nameof(selector));
return InnerZip();
IEnumerable<TResult> InnerZip()
{
using (var f = first.GetEnumerator())
using (var s = second.GetEnumerator())
{
var firstIteration = true;
while (f.MoveNext())
{
if (!s.MoveNext())
{
if (firstIteration)
{
yield break;
}
else
{
s.Reset();
s.MoveNext();
}
}
yield return selector(f.Current, s.Current);
firstIteration = false;
}
}
}
}
这应该可以解决问题。