【问题标题】:IEnumerable Casting 2 IEnumerables into one classIEnumerable 将 2 个 IEnumerable 转换为一个类
【发布时间】:2010-12-15 22:34:09
【问题描述】:

我有 2 个 IEnumerables

IEnumerable<float> Distance
IEnumerable<XElement> Point

我想转换成的

IEnumerable<Subsection> subsection

类在哪里

class Subsection
{
    public float Distance
    public XElement Point
}

但我不知道如何做到这一点,我尝试了一些转换的变体,但都没有奏效,因为它们似乎不接受多个列表作为输入。

距离和点变量是从 xml 文档中读取的,其中这两个点的结构类似于:

<PLI>
    <Distance>5</Distance>
    <Point>23 22</Point>
    <Distance>7</Distance>
    <Point>21 72</Point>
    <Distance>9</Distance>
    <Point>13 32</Point>
</PLI>

我不知道如何将它们简单地作为小节类型读出,但如果有人可以建议如何做到这一点,它将绕过我转换它的需要,因为我将不再将它们作为距离和点的 IEnumerables 但作为结构。

请注意我不能修改 XML

谢谢

编辑: XML 具有其他元素以及 PLI 标记中提到的元素,例如

<PLI>
    <OtherElement1>element1value</OtherElement1>
    <OtherElement2>element2value</OtherElement2>
    <Distance>5</Distance>
    <Point>23 22</Point>
    <Distance>7</Distance>
    <Point>21 72</Point>
    <Distance>9</Distance>
    <Point>13 32</Point>
</PLI>

【问题讨论】:

  • 更新了我的帖子以考虑其他元素。这仅影响非 LINQ 方法。 Zip 方法没有改变。

标签: .net xml linq-to-xml ienumerable


【解决方案1】:

您可以在Enumerable.Zip method 的帮助下使用 LINQ 完成此任务,前提是您的 XML 是平衡的(用于配对距离和点的元素数量为偶数)。

var query = xml.Elements("Distance")
               .Zip(xml.Elements("Point"),
                    (d, p) => new Subsection
                    {
                        Distance = float.Parse(d.Value),
                        Point = p
                    });

或者,您可以循环遍历元素并构建Subsection 项目。这可以按如下方式完成,尽管它假设您的 XML 文档是平衡的并且是预期的格式。

var query = xml.Elements()
               .Where(e => e.Name.LocalName == "Distance"
                           || e.Name.LocalName == "Point");
var list = new List<Subsection>();
int count = 0;
Subsection s = null;
foreach (var element in query)
{
    if (count % 2 == 0)
        s = new Subsection { Distance = float.Parse(element.Value) };
    else
    {
        s.Point = element;
        list.Add(s);
    }

    count++;
}

请注意,在两个 sn-ps 中,xml 变量都是 XElement。对于XDocument,添加Root 属性,如xml.Root.Elements(...)

【讨论】:

  • 更新了第二种过滤 DistancePoint 元素的方法并仅使用它们。同样,您需要确保它们是平衡的。如果您不确定,那么预先 .Count() 检查两个元素集合,检查它们的总和是否为偶数(模 2 == 0)就足够了。
  • 感谢 zip 功能正是我想要的,以前从未见过
【解决方案2】:

这不是引用透明且完全不可取的,但如果您对 LINQ 有信心,这是我目前针对此特定问题的最佳想法。这样可以保证您的订单是一样的。

public class SubSection
{
    public float Distance;
    public XElement Point;

    public SubSection(XElement distance, XElement point)
    {
        Distance = float.Parse(distance.Value);
        Point = point;
    }
}
class Program
{
    static void Main(string[] args)
    {
        var c = XDocument.Parse(@"<PLI>
<Distance>5</Distance>
<Point>23 22</Point>
<Distance>7</Distance>
<Point>21 72</Point>
<Distance>9</Distance>
<Point>13 32</Point>
</PLI>");

        var sup = new List<SubSection>();
        c.Elements().Elements().Aggregate<XElement,XElement>(null, (a, d) =>
            {
                if (a == null)
                    return d;
                sup.Add(new SubSection(a, d));
                return null;
            });
        foreach (var entry in sup)
        {
            Console.WriteLine(entry.Distance);
        }

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    相关资源
    最近更新 更多