应用排列以生成表格

时间:2015-11-17 09:41:39

标签: c# asp.net-mvc-5 permutation

我有以下键值对,我需要根据键找到所有组合。在图中,第一个表显示了所有键值对,第二个表显示了预期输出的提取。所有可能的组合都应该成为表格。

This is the extract of the table i am trying to build

public ActionResult ViewSystemValues ()
{
    var model = new List<ViewSystemValuesVM>();//Each item in Model consists of the Key Value pair mentioned in the question         
    var tclist = new List<TcSet>(); //Each item is the link to the Property that holds the key
    var tcid = new List<int>(); //List of distinct keys in tclist              

    //For simplicity I have eliminated the code that would populate the Lists  and the model with the description as comments

    string[] myArray = new string[tclist.Count()];
    var model1 = new List<String[]>();
    int tclistcount = tclist.Count();
    foreach(var x in model)
    {
        foreach (var item in model)
        for(int i=0;i<tclistcount;i++)
        {         
            if (tcid[i] == item.TcSetID)
                myArray[i] = item.Value; 
        }
        model1.Add(myArray);
    }
}

方法

myArray对应于我的置换表中的一行。 model包含有效的键值对。我检查modeltcid中的密钥是否相同,可以在myArray中添加与tcid索引相同的值,以便获取相应的值tcid

但我只得到最后一个可能的组合

colour  fruit    vegatable
yellow  banana    beans 
yellow  banana    beans 
yellow  banana    beans 
yellow  banana    beans 
yellow  banana    beans 
yellow  banana    beans 

2 个答案:

答案 0 :(得分:1)

这样做你想要的吗?

s.Length == 1

此查询中的此基本案例,new [] { new [] { "onion", "potato", "tomato", "beans" } }基本上将new [] { new [] { "onion", }, new [] { "potato", }, new [] { "tomato", }, new [] { "beans", }, }变为build。非基本情况递归调用Func<string[][], string[][]> build = null; build = s => ( s.Length == 1 ? from x in s[0] select new [] { x } : from xs in build(s.Skip(1).ToArray()) from x in s[0] select new [] { x }.Concat(xs).ToArray() ).ToArray(); ,然后将每个递归数组的开头追加到第一个数组的值。很高兴你问过?

或者我可以写这样的查询:

var source = new []
{
    new { Key = "colour", Value = "red", },
    new { Key = "colour", Value = "blue", },
    new { Key = "colour", Value = "violet", },
    new { Key = "colour", Value = "black", },
    new { Key = "colour", Value = "yellow", },
    new { Key = "fruit", Value = "apple", },
    new { Key = "fruit", Value = "mango", },
    new { Key = "fruit", Value = "banana", },
    new { Key = "vegetable", Value = "onion", },
    new { Key = "vegetable", Value = "potato", },
    new { Key = "vegetable", Value = "tomato", },
    new { Key = "vegetable", Value = "beans", },
};

string[][] data =
    source
        .ToLookup(x => x.Key, x => x.Value)
        .Select(x => x.ToArray())
        .ToArray();

这可能会帮助您更轻松地分解它。

如果我从这些数据开始:

new []
{
   new [] { "red", "apple", "onion" } 
   new [] { "blue", "apple", "onion" } 
   new [] { "violet", "apple", "onion" } 
   new [] { "black", "apple", "onion" } 
   new [] { "yellow", "apple", "onion" } 
   new [] { "red", "mango", "onion" } 
   new [] { "blue", "mango", "onion" } 
   new [] { "violet", "mango", "onion" } 
   new [] { "black", "mango", "onion" } 
   new [] { "yellow", "mango", "onion" } 
   new [] { "red", "banana", "onion" } 
   new [] { "blue", "banana", "onion" } 
   new [] { "violet", "banana", "onion" } 
   new [] { "black", "banana", "onion" } 
   new [] { "yellow", "banana", "onion" } 
   new [] { "red", "apple", "potato" } 
   new [] { "blue", "apple", "potato" } 
   new [] { "violet", "apple", "potato" } 
   new [] { "black", "apple", "potato" } 
   new [] { "yellow", "apple", "potato" } 
   new [] { "red", "mango", "potato" } 
   new [] { "blue", "mango", "potato" } 
   new [] { "violet", "mango", "potato" } 
   new [] { "black", "mango", "potato" } 
   new [] { "yellow", "mango", "potato" } 
   new [] { "red", "banana", "potato" } 
   new [] { "blue", "banana", "potato" } 
   new [] { "violet", "banana", "potato" } 
   new [] { "black", "banana", "potato" } 
   new [] { "yellow", "banana", "potato" } 
   new [] { "red", "apple", "tomato" } 
   new [] { "blue", "apple", "tomato" } 
   new [] { "violet", "apple", "tomato" } 
   new [] { "black", "apple", "tomato" } 
   new [] { "yellow", "apple", "tomato" } 
   new [] { "red", "mango", "tomato" } 
   new [] { "blue", "mango", "tomato" } 
   new [] { "violet", "mango", "tomato" } 
   new [] { "black", "mango", "tomato" } 
   new [] { "yellow", "mango", "tomato" } 
   new [] { "red", "banana", "tomato" } 
   new [] { "blue", "banana", "tomato" } 
   new [] { "violet", "banana", "tomato" } 
   new [] { "black", "banana", "tomato" } 
   new [] { "yellow", "banana", "tomato" } 
   new [] { "red", "apple", "beans" } 
   new [] { "blue", "apple", "beans" } 
   new [] { "violet", "apple", "beans" } 
   new [] { "black", "apple", "beans" } 
   new [] { "yellow", "apple", "beans" } 
   new [] { "red", "mango", "beans" } 
   new [] { "blue", "mango", "beans" } 
   new [] { "violet", "mango", "beans" } 
   new [] { "black", "mango", "beans" } 
   new [] { "yellow", "mango", "beans" } 
   new [] { "red", "banana", "beans" } 
   new [] { "blue", "banana", "beans" } 
   new [] { "violet", "banana", "beans" } 
   new [] { "black", "banana", "beans" } 
   new [] { "yellow", "banana", "beans" } 
}

我得到了这个结果:

var source = new []
{
    new { Key = "colour", Value = "red", },
    new { Key = "fruit", Value = "apple", },
    new { Key = "vegetable", Value = "onion", },
    new { Key = "nation", Value = "france", },
    new { Key = "nation", Value = "australia", },
};

这适用于任意数量的键。

试试这个数据:

new []
{
   new [] { "red", "apple", "onion", "france" } 
   new [] { "red", "apple", "onion", "australia" } 
}

我得到了这个结果:

int

如果您的密钥是var source = new[] { new { Key = 1, Value = "red", }, new { Key = 1, Value = "apple", }, new { Key = 2, Value = "onion", }, new { Key = 3, Value = "france", }, new { Key = 3, Value = "australia", }, }; string[][] data = source .ToLookup(x => x.Key, x => x.Value) .Select(x => x.ToArray()) .ToArray(); Func<string[][], string[][]> build = null; build = s => ( s.Length == 1 ? from x in s[0] select new[] { x } : from xs in build(s.Skip(1).ToArray()) from x in s[0] select new[] { x }.Concat(xs).ToArray() ).ToArray(); ,则代码的工作原理相同:

build

这是public string[][] Build(string[][] source) { return ( source.Length == 1 ? from x in source[0] select new[] { x } : from xs in Build(source.Skip(1).ToArray()) from x in source[0] select new[] { x }.Concat(xs).ToArray() ).ToArray(); } 的非匿名版本:

133 0.00295 nurse merit respect muslim 
134 0.00292 high dangerous reassure full 
135 0.00048 
136 0.0039  experience darren  
137 0.00097 _ _param_ui_control_scripts_save _param_pattern_value 
138 0.00292 find director

答案 1 :(得分:1)

这不是问题的真正答案。但是,当变量的数量固定时,可以采用一种方法。这种方法可以扩展到可变输入

   public ActionResult tablecreate()
    {
        string[] key = { "colour", "fruit", "vegetable" };
        var kvpair = new List<Tuple<String,String>>();
        kvpair.Add(new Tuple<String,String>("colour","red"));
        kvpair.Add(new Tuple<String, String>("colour", "blue"));
        kvpair.Add(new Tuple<String, String>("colour", "yellow"));
        kvpair.Add(new Tuple<String, String>("colour", "black"));
        kvpair.Add(new Tuple<String, String>("fruit", "mango"));
        kvpair.Add(new Tuple<String, String>("fruit", "apple"));
        kvpair.Add(new Tuple<String, String>("vegetable", "potato"));
        kvpair.Add(new Tuple<String, String>("vegetable", "tomato"));
        kvpair.Add(new Tuple<String, String>("vegetable", "beans"));
        var combi = new List<Tuple<String,String,String>>();
        int i = 0, j = 0, k = 0;
        var colorval = new List<String>();
        var fruitval = new List<String>();
        var vegval =new List<String>();
        foreach (var item in kvpair)
        {
            if (item.Item1 == "colour")
                colorval.Add(item.Item2);
            else if (item.Item1 == "fruit")
                fruitval.Add(item.Item2);
            else if (item.Item1 == "vegetable")
                vegval.Add(item.Item2);
        }
        foreach(var col in colorval)
        {
            foreach(var fru in fruitval)
            {
                foreach(var veg in vegval)
                {
                    combi.Add(new Tuple<string, string, string>(col, fru, veg));
                }
            }
        }

输出将生成问题中提到的表

我可以使用以下代码获取属于每个键的值,但仍然缺少组合

  var serialize = new List<Tuple<int, List<string>>>();

 for(int i=0;i<tcid.Count();i++)
 {
       var val = new List<string>();
       foreach(var item in model)
       {
           if(tcid[i]==item.TcSetID)
                val.Add(item.Value);        
       }
       serialize.Add(new Tuple<int,List<string>>(tcid[i],val));
  }

现在serailize我们拥有每个键的所有可能值。

为了使其更清晰serailize仅用作变量名。 serailise列表与上面代码中的colorvalfruitvalvegval类似,具有恒定数量的变量。

所以serailize将保持以下值:

serialize [item1 :colour, item2 : {blue,red,black,yellow}]
serialize [item1 :fruit, item2 : {apple,mango}]
serialize [item1 :vegetable, item2 : {tomato,potato,beans}]

我有一个函数可以在serialize.item2

中找到两个项目的笛卡尔积
public List<String> Cartesian (List<String> A, List<String> B)
{
    int Alenght = A.Count();
    int Blength = B.Count();
    var S = new List<String>();
    for (int i = 0; i < Alenght;i++ )
    {
       for(int j=0;j<Blength;j++)
       {
           S.Add(A[i] + "delim" + B[j]);
       }
    }
    return S;
}

该函数调用如下

 var A = new List<String>();
 foreach(var item in serialize)
 {
     if(j==0)
     {
         A = item.Item2;
         j = 1;    
     }
     else
         A =  Cartesian(A, item.Item2);
  }

然后将列表A中的字符串作为字符串数组

 //distinctlist contains all the distinct strings in A
 foreach(var item in distinctlist)
 {
     var row = new ViewsVM();
     row.row = item.Split(new string[] { "delim"},StringSplitOptions.None);
     ViewsVM.Add(row);
 }

<强> ViewsVM

public class ViewsVM
{ 
    public string[] row  { get; set; }
}

希望它有所帮助。但我应该警告这不是最好的方法。

Enigmativity 可以更好地解决问题。我发布这个答案只是因为我还找到了替代方法。