2016-09-20 3 views
0

У меня проблема с комбинацией. То, что я получил, это 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 im. Мне нужно создать экземпляр для каждого DataField.Value.

Szenario is: Я получил List<IDataField>, например.

и я хочу, чтобы создать List<List<FieldProperties>> со всеми возможными комбинациями значений DataField.

+0

Вы можете добавить пример ввода, и это соответствие вывод? – Maarten

+0

Что такое 'FieldProperties'? Каково ваше * актуальное * требование здесь? Я имею в виду, кажется, что это ужасное техническое решение для какой-то проблемы с готовностью, если честно. – MarioDS

+0

Итак, вы хотите, чтобы объекты '' DataField' 'менялись, в соответствии с которыми авторы находятся в списке значений? Итак, вы должны были бы: «1,2,3',' 1,2', '1,3',' 2,3', '1',' 2' и '3' в поле« Значения »? Это похоже на очень странную вещь, которую нужно хотеть, поэтому просто хочу убедиться, что я правильно понимаю. Также я был бы склонен к MarioDS, что это немного похоже на плохое решение другой проблемы ... – Chris

ответ

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

Спасибо за помощь. Я пытаюсь понять ваше решение, но я не понимаю точку с запятой без каких-либо заявлений. Можете ли вы дать мне модное слово для Google? – user3292642

+0

Это просто 'for' с отсутствующей первой частью (инициализатор). Как вы можете видеть здесь [для (ссылка на C#)] (https://msdn.microsoft.com/en-us/library/ch45axte.aspx), каждый оператор 'for' имеет 3 раздела -' for (initializer; condition; итератор), и любой из них является необязательным. –

Смежные вопросы