2016-08-22 12 views
0

класс демо:Динамический декартовой Продукт

class item 
{ 
    public string name { get; set; } 
    public int level { get; set; } 
} 

данные демо:

List<item> all = new List<item>(); 
all.Add(new item { name = "Red", level = 0 }); 
all.Add(new item { name = "Blue", level = 0 }); 

all.Add(new item { name = "S", level = 1 }); 
all.Add(new item { name = "M", level = 1 }); 
all.Add(new item { name = "L", level = 1 }); 

all.Add(new item { name = "Man", level = 2 }); 
all.Add(new item { name = "Woman", level = 2 }); 

мне нужна группа по уровне и объединить все имя, Это декартова продукта вопрос. В результате, как это:

красный - S - Человек
красный - S - Женщина
Красный - М - Человек
Красный - M - Женщина
Красный - L - Человек
Красный - L - Женщина
Blue - S - Человек
Синий - S - Женщина
Blue - M - Man
Blue - M - Женщина
Blu е - L - Man
Blue - L - Женщина

Если уровень был установлен, решение с сильфоном кодом:

foreach(var _0 in all.Where(m => m.level == 0)) 
{ 
    foreach(var _1 in all.Where(m => m.level == 1)) 
    { 
     foreach(var _2 in all.Where(m => m.level == 2)) 
     { 
      Console.WriteLine(_0.name + "-" + _1.name + "-" + _2.name); 
     } 
    } 
} 

Но большой вопрос: уровень динамичен, я просто кодированием, как это :

for(int i = 0; i < level; i++) 
{ 
    //some code ... 
} 

Поскольку мой реальный проект Javascript, поэтому, пожалуйста, дайте мне простой код (не LINQ), спасибо очень много, чтобы помочь.

+0

Пожалуйста, отметьте ваши вопросы на этом языке, не включайте его в заголовок. –

ответ

0

Я хотел бы начать с построения списка, содержащего элементов на каждом уровне:

var levels = new List<List<item>>(); 
foreach (var item in all) 
{ 
    while (levels.Count <= item.level) 
     levels.Add(new List<item>()); 
    levels[item.level].Add(item); 
} 

, а затем заполнить результат с помощью простого рекурсивного метода:

var result = new List<string>(); 
AddCombinations(result, levels, 0, null); 

где метод является:

static void AddCombinations(List<string> result, List<List<item>> levels, int level, string path) 
{ 
    if (level >= levels.Count) 
    { 
     result.Add(path); 
     return; 
    } 
    foreach (var item in levels[level]) 
     AddCombinations(result, levels, level + 1, path == null ? item.name : path + " - " + item.name); 
} 

Вместо рекурсии я мог бы настроить реализацию из своего ответа на Every combination of "1 item from each of N collections", чтобы построить результат итеративно на месте, если хотите, но я думаю, что этого было достаточно.

+0

очень хорошо, tks очень много. Я могу использовать его в Javascript. –

0

Что-то, как это должно работать:

var lines = CartesianProduct(all, 0); 
foreach(var line in lines) { 
    Console.WriteLine(line); 
} 

List<string> CartesianProduct(List<item> items, int level) { 
    List<string> result = new List<string>(); 
    List<string> itemsOnThisLevel = new List<string>(); 
    foreach(var it in items) { 
     if (it.level == level) itemsOnThisLevel.Add(it.name); 
    } 
    if (!itemsOnThisLevel.Any()) { 
     result.Add(""); 
     return result; 
    } 
    var itemsOnLowerLevels = CartesianProduct(items, level+1); 
    foreach(var it in itemsOnThisLevel) { 
     foreach(var it2 in itemsOnLowerLevels) { 
     result.Add(it2 + " - " + it); 
     } 
    } 
    return result 
} 

EDIT: убрана выражения Linq как автор просил.

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

  • Нет связанных вопросов^_^