IEnumerable Casting 2 IEnumerables в один класс - PullRequest
1 голос
/ 13 декабря 2010

У меня есть 2 IEnumerables

IEnumerable<float> Distance
IEnumerable<XElement> Point

, которые я хочу преобразовать в

IEnumerable<Subsection> subsection

, где класс

class Subsection
{
    public float Distance
    public XElement Point
}

Но я понятия не имею, какчтобы сделать это, я попробовал несколько вариантов приведения, ни один из которых не работал, потому что они, кажется, не принимают несколько списков в качестве входных данных.

Переменные Distance и 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>

Ответы [ 2 ]

1 голос
/ 13 декабря 2010

Вы можете выполнить это с помощью LINQ с помощью метода Enumerable.Zip , при условии, что ваш 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++;
}

Обратите внимание, что в обоих фрагментах переменная xml представляет собой XElement.Для XDocument добавьте свойство Root, как в xml.Root.Elements(...).

1 голос
/ 13 декабря 2010

Это нереально прозрачно и совершенно нецелесообразно, но если вы настроены на 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);
        }

    }
}
...