简体   繁体   English

组列表<object>带有键和不同值的计数<div id="text_translate"><p>我正在尝试提出一个解决方案来对给定的键和值列表进行分组。</p><p> 我需要像这样对它进行分组:Key &gt; Dicttinct Value &gt; Count。</p><p> 例如</p><pre>XFN99 2 3 &lt;= [CODE] [DISTINCT_VALUE] [OCCURANCE IN LIST]</pre><p> 我有一个返回List&lt;ObjectPart&gt;的方法。 此 object 具有public string code和public int value 。</p><p> 我需要获取键中每个不同值的计数。</p><p> 示例输入:</p><pre> XFN999 2 XFN999 2 XFN999 2 XFN999 4 XFN999 8 XFN999 8 XFN999 8 BPN655 1 BPN675 2 BPN655 1</pre><p> 所需的 Output:</p><pre> XFN999 2 =&gt; 3x XFN999 4 =&gt; 1x XFN999 8 =&gt; 3x BPN655 1 =&gt; 2x BPN675 2 =&gt; 1x</pre><p> 我试图 LINQ 以我的方式成功但失败了,因为它对每个键的值求和。</p><pre> var distValsPerKey = S.getAllDiffs().Result.GroupBy(x =&gt; x.code).Select(x =&gt; new { C_ = x.Key, V_ = x.Distinct().Count() });</pre><p> Output 与我的解决方案:</p><pre> BPN373 =&gt; 30 BPN374 =&gt; 35 BPN377 =&gt; 47 BPN378 =&gt; 43 BPN387 =&gt; 67 BPN388 =&gt; 49 BPN653 =&gt; 10 BPN654 =&gt; 15 BPN699 =&gt; 40 BPN700 =&gt; 45 BPN711 =&gt; 68 BPN723 =&gt; 13 BPN724 =&gt; 11 BPN853 =&gt; 5 BPN854 =&gt; 6 BPN877 =&gt; 99 BPN878 =&gt; 94 BPN505 =&gt; 92 BPN507 =&gt; 570 BPN508 =&gt; 617</pre><p> 我的解决方案基本上对 key 的值求和,但<strong>我需要对每个 key 的不同值求和/计数</strong>。</p><p> 下面的例子:</p><p> <strong>Getting input of List&lt;ObjectPart&gt;</strong></p><pre> public async Task&lt;List&lt;ObjectPart&gt;&gt; getAllDiffs() { List&lt;ObjectPart&gt; TEMP = new List&lt;ObjectPart&gt;(); await Task.Run(() =&gt; { using (IngresConnection CONN = new IngresConnection()) { string QUERRY = SELECT_REDACTED; try { using (IngresCommand CMD = new IngresCommand()) { CONN.ConnectionString = "host=; userID=; pwd=; database=;"; CMD.Connection = CONN; CMD.CommandText = QUERRY; CONN.Open(); using (IngresDataReader READ = CMD.ExecuteReader()) { while (READ.Read()) { ObjectPart OP = new ObjectPart(); OP.wenr = READ.GetValue(0).ToString().Trim(); OP.difference = Convert.ToInt32(READ.GetInt32(1)); TEMP.Add(OP); } READ.Close(); CONN.Close(); } } } catch (Exception E) { CONN.Close(); CONN.Dispose(); } } }); List&lt;ObjectPart&gt; OPS_SORTED = TEMP.OrderBy(m =&gt; m.code).ToList(); return OPS_SORTED; }'</pre><p> <strong>LINQ the input to get desired output</strong></p><pre> var distValsPerKey = S.getAllDiffs().Result.GroupBy(x =&gt; x.code).Select(x =&gt; new { C_ = x.Key, V_ = x.Distinct().Count() }); foreach(var OP in distValsPerKey) { Console.WriteLine($"{OP.C_} = &gt; {OP.V_}"); }</pre></div></object>

[英]Group List<Object> with keys and distinct values count

I'm trying to come up with a solution to group a given list of keys and values.我正在尝试提出一个解决方案来对给定的键和值列表进行分组。

I need to group it like this: Key > Dictinct Value > Count.我需要像这样对它进行分组:Key > Dicttinct Value > Count。

Eg例如

XFN99 2 3 <= [CODE] [DISTINCT_VALUE] [OCCURANCE IN LIST]

I have a method that returns List<ObjectPart> .我有一个返回List<ObjectPart>的方法。 This object has a public string code and public int value .此 object 具有public string codepublic int value

I need to get count per distinct value in a key.我需要获取键中每个不同值的计数。

Example Input:示例输入:

XFN999 2
XFN999 2
XFN999 2
XFN999 4
XFN999 8
XFN999 8
XFN999 8
BPN655 1
BPN675 2
BPN655 1

Desired Output:所需的 Output:

XFN999 2 => 3x
XFN999 4 => 1x
XFN999 8 => 3x
BPN655 1 => 2x
BPN675 2 => 1x

I tried to LINQ my way to success but failed, as it sums values per key.我试图 LINQ 以我的方式成功但失败了,因为它对每个键的值求和。

var distValsPerKey = S.getAllDiffs().Result.GroupBy(x => x.code)
                                        .Select(x => new { C_ = x.Key, V_ = x.Distinct().Count() });

Output with my solution: Output 与我的解决方案:

BPN373 => 30
BPN374 => 35
BPN377 => 47
BPN378 => 43
BPN387 => 67
BPN388 => 49
BPN653 => 10
BPN654 => 15
BPN699 => 40
BPN700 => 45
BPN711 => 68
BPN723 => 13
BPN724 => 11
BPN853 => 5
BPN854 => 6
BPN877 => 99
BPN878 => 94
BPN505 => 92
BPN507 => 570
BPN508 => 617

My solution basically sums values for key, but I need to sum/count distinct values per key .我的解决方案基本上对 key 的值求和,但我需要对每个 key 的不同值求和/计数

Example below:下面的例子:

Getting input of List<ObjectPart>

public async Task<List<ObjectPart>> getAllDiffs()
        {

            List<ObjectPart> TEMP = new List<ObjectPart>();

            await Task.Run(() =>
            {
                using (IngresConnection CONN = new IngresConnection())
                {
                    string QUERRY = SELECT_REDACTED;

                    try
                    {
                        using (IngresCommand CMD = new IngresCommand())
                        {

                            CONN.ConnectionString = "host=; userID=; pwd=; database=;";
                            CMD.Connection = CONN;
                            CMD.CommandText = QUERRY;
                            CONN.Open();
                            using (IngresDataReader READ = CMD.ExecuteReader())
                            {
                                while (READ.Read())
                                {
                                    ObjectPart OP = new ObjectPart();

                                    OP.wenr = READ.GetValue(0).ToString().Trim();
                                    OP.difference = Convert.ToInt32(READ.GetInt32(1));

                                    TEMP.Add(OP);
                                }
                                READ.Close();
                                CONN.Close();
                            }
                        }
                    }
                    catch (Exception E)
                    {
                        CONN.Close();
                        CONN.Dispose();
                    }
                }
            });
            List<ObjectPart> OPS_SORTED = TEMP.OrderBy(m => m.code).ToList();

            return OPS_SORTED;
        }'

LINQ the input to get desired output

 var distValsPerKey = S.getAllDiffs().Result.GroupBy(x => x.code).Select(x => new { C_ = x.Key, V_ = x.Distinct().Count() });
        
                        foreach(var OP in distValsPerKey)
                        {
                            Console.WriteLine($"{OP.C_} = > {OP.V_}");
                        }

Given the following input:给定以下输入:

List<(string code, int value)> input = new()
{
    ("XFN999", 2),
    ("XFN999", 2),
    ("XFN999", 2),
    ("XFN999", 4),
    ("XFN999", 8),
    ("XFN999", 8),
    ("XFN999", 8),
    ("BPN655", 1),
    ("BPN675", 2),
    ("BPN655", 1),
};

You can get the required output data like this:您可以获得所需的 output 数据,如下所示:

List<(string code, int value, int occurrences)> output =
    input
        .GroupBy(x => new { x.code, x.value })
        .Select(x => (x.Key.code, x.Key.value, x.Count()))
        .ToList();

输出

To display this in the way you're after, do this:要以您所追求的方式显示它,请执行以下操作:

foreach (var o in output)
    Console.WriteLine($"{o.code} {o.value} => {o.occurrences}");

That gives me:这给了我:

XFN999 2 => 3
XFN999 4 => 1
XFN999 8 => 3
BPN655 1 => 2
BPN675 2 => 1

You want to group by code AND value, right?您想按代码和值分组,对吗? So do that in your GroupBy:所以在你的 GroupBy 中这样做:

var distValsPerKey = S.getAllDiffs().Result
    .GroupBy(x => new { x.code, x.value })
    .Select(x => new { C_ = x.Key, V_ = x.Distinct().Count() });

The rest of your code should work as it is, although if you output the Key of the GroupBy object it won't have quite the format you want.您的代码的 rest 应该按原样工作,尽管如果您 output 是 GroupBy object 的密钥,则它不会完全符合您想要的格式。 I get results as below:我得到如下结果:

{ code = XFN999, value = 2 } => 3
{ code = XFN999, value = 4 } => 1
{ code = XFN999, value = 8 } => 3
{ code = BPN655, value = 1 } => 2
{ code = BPN675, value = 2 } => 1

If that isn't what you want and you want C_ to be the text string in your example output then change the Select:如果这不是您想要的,并且您希望 C_ 成为示例 output 中的文本字符串,则更改 Select:

var distValsPerKey = S.getAllDiffs().Result
    .GroupBy(x => new { x.code, x.value })
    .Select(x => new { C_ = $"{x.Key.code} {x.Key.value}", 
                       V_ = x.Distinct().Count() });

This gives output:这给出了 output:

XFN999 2 => 3
XFN999 4 => 1
XFN999 8 => 3
BPN655 1 => 2
BPN675 2 => 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM