是否有一种方法可以在ObservableCollection中获得所有可能的组合?
我有个这样的模特:
public string MyProperty { get; set; }
public string MyProperty2 { get; set; }
public string MyProperty3 { get; set; }
public string MyProperty4 { get; set; }
public string MyProperty5 { get; set; }
public string MyProperty6 { get; set; }
public string MyProperty7 { get; set; }
public string MyProperty8 { get; set; }我用电子表格中的数据填充这个模型,但是有些值有零值或空值(我需要排除这些值)。是否有一种方法可以得到所有可能具有相同模式的组合?
例如,所有属性中的值与0不同的所有组合,以及只有一个属性和值的所有组合,以及其他属性为零的组合,等等。
到目前为止,我有这样的事情:
var group1 = _sourceStructure.Where(c => c.MyProperty != "0" && c.MyProperty2 != "0" && c.MyProperty3 != "0" && c.MyProperty4 != "0"
&& c.MyProperty5 != "0" && c.MyProperty6 != "0" && c.MyProperty7 != "0" && c.MyProperty8 != "0");但是,我需要用30多个案例来评估,是否有办法使用LINQ或其他解决方案获得所有可能的组合?
我希望使用集合中的值构建SQL查询,但是如果值为0或为空,则不会将该值添加到查询中。我希望获得具有相同模式的所有组合,以便能够将具有相同模式的所有项放入SQL中的in中。
输出数据如下所示:
string query = @"Select field1, field2, field3, fieldn FROM table WHERE "
query = query + "field1 = " + _sourceStructure.MyProperty1;
query = query + "fieldN = " + _sourceStructure.MyPropertyN;基本上,我不在乎价值是多少。我只需要用相同模式的所有可能组合对集合进行分组。
Excel中原始文件中的数据示例:
MyProperty1 MyPropert2 MyPropertN
Row1 0 1 3
Row2 2 0 6
Row3 0 5 9
Row4 9 9 4
Row5 4 3 6
Row6 0 0 0例如,在这里,我期望Row1和Row3在同一个组中(值不是相同的,而是“结构”相同),然后Row4和Row5将是另一个组,Row6是另一个组,Row2是另一个组。
发布于 2019-05-07 22:44:33
您可以使用反射来获取名为MyPropertyn的所有属性,其中n等于1,然后可以使用List of PropertyInfos来计算填充属性的位掩码,并根据该值进行分组。
首先,我使用了一些扩展方法:
public static class StringExt {
public static string Past(this string s, string starter) {
var starterPos = s.IndexOf(starter);
return starterPos == -1 ? String.Empty : s.Substring(starterPos + starter.Length);
}
}
public static class NumericExt {
public static int ToInt<T>(this T obj) => Convert.ToInt32(obj);
public static int IntPow(this int x, int pow) {
int ans = 1;
while (pow != 0) {
if ((pow & 0x1) == 1)
ans *= x;
x *= x;
pow >>= 1;
}
return ans;
}
}现在您可以收集感兴趣的属性,排序,然后计算每一行的位掩码:
var myPropInfos = typeof(COC).GetProperties()
.Where(pi => pi.Name.StartsWith("MyProperty"))
.OrderBy(pi => pi.Name.Past("MyProperty").ToInt()) // just in case properties aren't ordered
.ToList();
var GroupedFilters = src.Select(r => new { r, ValuedMask = myPropInfos.Select((pi, p) => pi.GetValue(r).ToString() != "0" ? 2.IntPow(p) : 0).Sum() })
.GroupBy(rm => rm.ValuedMask, rm => rm.r);如果第一个属性没有以整数结尾,您将需要一个测试来以顺序处理该属性,或者,或者,(特别是如果属性没有全部以数字结尾),您可以不使用OrderBy并使用GetProperties返回的任何顺序--顺序并不重要。返回的答案是每个值属性组合的IGrouping,Key是位掩码,显示哪些属性是值的。
如果您有超过31个属性,您应该切换到使用long并创建明显的LongPow扩展方法(2L.LongPow(p) : 0L)。
发布于 2019-05-07 20:41:47
你的桌子上有这样的东西:
Observable Property Value
A 1 0
A 2 1
A 3 2
B 1 0
B 2 0
B 3 1
C 1 1
C 2 2
C 3 3所有属性中值与0不同的所有组合:
SELECT Observable
FROM Table
GROUP BY Observable
HAVING SUM(CASE WHEN VALUE = 0 THEN 1 ELSE 0 END) = 0当只有一个具有值的属性,而其他属性为零时,所有组合:
SELECT Observable
FROM Table
GROUP BY Observable
HAVING COUNT(CASE WHEN VALUE > 0 THEN 1 END) = 1SQL演示
https://stackoverflow.com/questions/56030025
复制相似问题