【问题标题】:Dynamic way to flatten arrays in classes?在类中展平数组的动态方法?
【发布时间】:2015-12-11 21:34:09
【问题描述】:

我正在遍历包含双精度数组的对象。名字变了。想象一下这是一个 Lab samples 的对象,我正在尝试获取 Sample 对象的平面表示。

发件人:

Sample
{
    public string Name
    public string Type
    ...
    public double[] RawReadings
}

例如:

Name,
RawRead1,
RawRead2,
RawRead3,
...
RawReadn

如何获取 sample.RawReadings 以提供数组中的所有 n 个项目? 我不在乎它是否被命名。

为清楚起见进行编辑:我希望结果列表中的每个项目都具有名称,并且类中的属性与 RawReads 一样多。我确实希望结果列表中的每个项目都有一个名称和一个数组 - 这与我所拥有的相同。

示例 LinQ:

from sample in Samples
select new
{
    Name = sample.Name,
    sample.RawReadings
}

这可能吗?

编辑: 我将其提供给第 3 方 API 调用,该调用期望“行和列格式”的某些内容。准确地说是 Aspose.Cells ImportCustomObject。可能可以通过多次调用并手动对齐它们来解决它,但这可能很棘手并且容易出错。

【问题讨论】:

  • 您的问题不清楚。您想要一个包含名称和读数的对象的结果列表,以获取样本中的原始读数吗?
  • 没错,但是原始读数的结果列表不应该而是包含在列表的每个项目中的数组中。换句话说,列表不应该包含 Name 和 List,而是 Name 和 n 加倍。
  • 这个人 15 分钟前问了一个非常相似的问题:stackoverflow.com/q/32588070/495455
  • @JeremyThompson 只是有点相似。看起来 OP 想要为 RawReadings 中的每个双精度添加一个属性。
  • 也许您应该首先解释为什么要尝试这样做,因为您可能会问XY Problem

标签: c# arrays linq dynamic-programming dynamic-arrays


【解决方案1】:

我希望结果列表中的每个项目都具有名称和与 RawReads 一样多的双精度值。

你不能使用匿名类型来做到这一点。匿名类型具有在编译时指定的属性名称和类型,而您希望在执行时指定它们。目前尚不清楚您为什么要尝试这样做,但最接近的方法是使用动态类型,您可以使用扩展:

public dynamic SampleToDynamic(Sample sample)
{
    IDictionary<string, object> expando = new ExpandoObject();
    expando["Name"] = sample.Name;
    for (int i = 0; i < sample.RawReadings.Length; i++)
    {
        expando["RawRead" + (i + 1)] = sample.RawReadings[i];
    }
    return expando;
}

【讨论】:

  • 谢谢。我本可以实施另一种解决方案,但我很好奇这是否可能。你的回答对我来说很有意义,而且很有教育意义。我会稍微开放一下,以防梦到更多精彩的黑客。 :)
  • sample.RawReadings.Count()
  • @ArghyaC:哎呀,还以为是List&lt;T&gt;。改为Length
【解决方案2】:

假设你有这样的数据,

var samples = new List<Sample>();
samples.Add(new Sample { Name = "A", Type = "TypeA", RawReadings = new double[] { 1.5, 2.5, 3.5 } });
samples.Add(new Sample { Name = "B", Type = "TypeB", RawReadings = new double[] { 1.6, 2.6, 3.6 } });

你想要类似的东西

A 1.5
A 2.5
A 3.5
B 1.6
B 2.6
C 3.6

您可以使用此代码

var sampleReadings = new List<KeyValuePair<string, double>>();
samples.ForEach(s => 
            s.RawReadings.ToList().ForEach(r => 
                                    sampleReadings.Add(new KeyValuePair<string, double>(s.Name, r))));

【讨论】:

    【解决方案3】:

    假设您有这样的示例数据(这里我将 RawReadings 表示为逗号分隔,但实际上它们是双精度数组):-

    Name     Type      RawReadings
    --------------------------------
    foo      bar         1.2, 3.5, 4.8
    foo1     bar1        8.3, 6.6
    

    据我了解,您需要将所有 RawReadings 值作为具有名称和类型的新属性来获取。但正如@JonSkeet 已经解释的那样,这是不可能的。可以将RawReadings 数据展平并将其与Sample 类的其他属性结合起来,如下所示:-

    Name     Type     RawReadings
    --------------------------------
    foo      bar       1.2
    foo      bar       3.5
    foo      bar       4.8
    foo1     bar1      8.3
    foo1     bar1      6.6
    

    下面是代码:-

    var result = sampleData
             .SelectMany(x => x.RawReadings, (sampleObj, rawObj) => new { sampleObj, rawObj })
             .Select(x => new
                         {
                              Name = x.sampleObj.Name,
                              Type = x.sampleObj.Type,
                              raws = x.rawObj
                          });
    

    【讨论】:

    • 谢谢,我确实在寻找不可能的情况。只有一个 foo 和一个 bar。喜欢: foo bar 1.2 3.5 4.8 ; foo1 bar1 8.3 6.6
    猜你喜欢
    • 2015-06-16
    • 2017-07-17
    • 2020-07-11
    • 2012-05-01
    • 2019-08-03
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多