C# 使用LINQ to XML,如何根据顺序位置连接两组数据?

C# 使用LINQ to XML,如何根据顺序位置连接两组数据?,c#,xml,linq,linq-to-xml,C#,Xml,Linq,Linq To Xml,使用LINQ to XML,如何根据顺序位置连接两组数据 <document> <set1> <value>A</value> <value>B</value> <value>C</value> </set1> <set2> <value>1</value>

使用LINQ to XML,如何根据顺序位置连接两组数据

<document>
    <set1>
        <value>A</value>
        <value>B</value>
        <value>C</value>
    </set1>
    <set2>
        <value>1</value>
        <value>2</value>
        <value>3</value>
    </set2>
</document>

A.
B
C
1.
2.
3.
基于上面的片段,我想将这两个集合连接在一起,这样“A”和“1”在同一条记录中,“B”和“2”在同一条记录中,“C”和“3”在同一条记录中。

这就是扩展在.NET 4中所做的。您可以这样写(假设这是整个
XDocument
):

如果您使用的是.NET 3.5或更早版本,编写
Zip
扩展并不太困难:

public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(
    this IEnumerable<TFirst> first,
    IEnumerable<TSecond> second,
    Func<TFirst, TSecond, TResult> resultSelector)
{
    using (var firstEnumerator = first.GetEnumerator())
    using (var secondEnumerator = second.GetEnumerator())
    {
        while ((firstEnumerator.MoveNext() && secondEnumerator.MoveNext()))
        {
            yield return resultSelector(firstEnumerator.Current,
                secondEnumerator.Current);
        }
    }
}
公共静态IEnumerable Zip(
这是第一次,
我数不清的秒,
Func结果选择器)
{
使用(var firstEnumerator=first.GetEnumerator())
使用(var secondEnumerator=second.GetEnumerator())
{
while((firstEnumerator.MoveNext()&&secondEnumerator.MoveNext())
{
产生返回结果选择器(firstEnumerator.Current,
第二个枚举器(当前);
}
}
}
这就是扩展在.NET 4中的作用。您可以这样写(假设这是整个
XDocument
):

如果您使用的是.NET 3.5或更早版本,编写
Zip
扩展并不太困难:

public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(
    this IEnumerable<TFirst> first,
    IEnumerable<TSecond> second,
    Func<TFirst, TSecond, TResult> resultSelector)
{
    using (var firstEnumerator = first.GetEnumerator())
    using (var secondEnumerator = second.GetEnumerator())
    {
        while ((firstEnumerator.MoveNext() && secondEnumerator.MoveNext()))
        {
            yield return resultSelector(firstEnumerator.Current,
                secondEnumerator.Current);
        }
    }
}
公共静态IEnumerable Zip(
这是第一次,
我数不清的秒,
Func结果选择器)
{
使用(var firstEnumerator=first.GetEnumerator())
使用(var secondEnumerator=second.GetEnumerator())
{
while((firstEnumerator.MoveNext()&&secondEnumerator.MoveNext())
{
产生返回结果选择器(firstEnumerator.Current,
第二个枚举器(当前);
}
}
}

下面是另一个使用Select重载的方法,该方法将包括元素的索引

XElement set1 = document.Root.Element("set1");
XElement set2 = document.Root.Element("set2");

var query = from value1 in set1.Descendants("value").Select((ele, idx) => new { Value = ele.Value, Index = idx })
            join value2 in set2.Descendants("value").Select((ele, idx) => new { Value = ele.Value, Index = idx })
            on value1.Index equals value2.Index
            select new { Value1 = value1.Value, Value2 = value2.Value };

下面是另一个使用Select重载的方法,它将包含元素的索引

XElement set1 = document.Root.Element("set1");
XElement set2 = document.Root.Element("set2");

var query = from value1 in set1.Descendants("value").Select((ele, idx) => new { Value = ele.Value, Index = idx })
            join value2 in set2.Descendants("value").Select((ele, idx) => new { Value = ele.Value, Index = idx })
            on value1.Index equals value2.Index
            select new { Value1 = value1.Value, Value2 = value2.Value };