获得所有项目的组合
本文关键字:组合 项目 | 更新日期: 2023-09-27 18:07:47
我遇到了一个组合问题。我得到的是Data
类,它基本上包含一个name
和一个values
列表:
public abstract class DataField : IDataField
{
public string Name { get; set; }
public List<string> Values { get; set; }
}
在运行时,我要做的是得到一个List<DataField>
对象的每一个可能的组合。到目前为止,我尝试的是:
// Get dataFields with values
List<IDataField> propertyDataFields = mDataFields.Where(x => x.Values.Count > 0).ToList();
var props = GetPropertiesList(propertyDataFields, 0, propertyDataFields.Count - 1, new List<List<FieldProperties>>());
private static List<List<FieldProperties>> GetPropertiesList(List<IDataField> propertyDataFields, int listPosition, int position, List<List<FieldProperties>> fieldPropertiesList)
{
var fieldProperties = new List<FieldProperties>();
foreach (var item in propertyDataFields[position].Values)
{
if (position == -1)
{
GetPropertiesList(propertyDataFields, listPosition + 1, propertyDataFields.Count - 1, fieldPropertiesList);
}
fieldProperties.Add(new FieldProperties(propertyDataFields[position].Name, item));
GetProperties(propertyDataFields, position - 1, fieldProperties, fieldPropertiesList);
}
return fieldPropertiesList;
}
private static void GetProperties(List<IDataField> propertyDataFields, int position, List<FieldProperties> fieldProperties, List<List<FieldProperties>> fieldPropertiesList)
{
if (position == -1)
{
fieldPropertiesList.Add(fieldProperties);
}
foreach (var item in propertyDataFields[position].Values)
{
fieldProperties.Add(new FieldProperties(propertyDataFields[position].Name, item));
GetProperties(propertyDataFields, position - 1, fieldProperties, fieldPropertiesList);
}
}
最后,我需要一个FieldProperties
对象列表的列表。我们的想法是从列表中的最后一个dataField
开始,每次使用foreach
循环所有其他的,但是如果第一个列表只有1
项,这将不起作用。也许按Values
排序。Count
是个想法?
FieldProperties
是一个类从另一个dll我使用。我需要为每个DataField.Value创建一个实例。场景是:我有一个List<IDataField>
例如
var dataFieldAuthor = new DataField() {
Name = "Author"
Values = new List<string> { "Author1", "Author2", "Author3" };
}
和我想创建一个List<List<FieldProperties>>
与所有可能的组合的数据字段值
你可以使用从我的答案的通用方法如何迭代不同长度的列表来找到所有的排列?:
public static class Algorithms
{
public static IEnumerable<T[]> GenerateCombinations<T>(this IReadOnlyList<IReadOnlyList<T>> input)
{
var result = new T[input.Count];
var indices = new int[input.Count];
for (int pos = 0, index = 0; ;)
{
for (; pos < result.Length; pos++, index = 0)
{
indices[pos] = index;
result[pos] = input[pos][index];
}
yield return result;
do
{
if (pos == 0) yield break;
index = indices[--pos] + 1;
}
while (index >= input[pos].Count);
}
}
}
结合LINQ:
var fields = mDataFields.Where(x => x.Values.Count > 0).ToList();
var result = fields
.Select(df => df.Values).ToList()
.GenerateCombinations()
.Select(c => c.Select((v, i) => new FieldProperties(fields[i].Name, v)).ToList())
.ToList();