获取所有项目组合

时间:2016-09-20 11:41:56

标签: c# algorithm

我遇到了组合问题。 我得到的是一个Data类,它基本上包含namevalues列表:

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创建一个实例。

szenario是:我得到了List<IDataField>,例如

  var dataFieldAuthor = new DataField() {
  Name = "Author"
  Values = new List<string> { "Author1", "Author2", "Author3" };
  }

我希望创建一个List<List<FieldProperties>>,其中包含所有可能的DataField值组合。

1 个答案:

答案 0 :(得分:1)

您可以使用我对How to iterate lists with different lengths to find all permutations?的回答中的通用方法:

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();