首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果你有一个使用Select()方法的LINQ语句,有没有办法从下一条记录中获取一个值?

如果你有一个使用Select()方法的LINQ语句,有没有办法从下一条记录中获取一个值?
EN

Stack Overflow用户
提问于 2013-05-23 03:59:40
回答 5查看 1.2K关注 0票数 2

我有以下LINQ语句:

代码语言:javascript
复制
IEnumerable<Statement> statement = bookmarkCollection.AsEnumerable().Select(
bookmark => new Statement()
{
    Title = bookmark.Title,
    PageNumber = bookmark.PageNumber
});

语句有另一个名为NextPageNumber的属性,我需要能够填充该属性。NextPageNumber等于下一条记录的PageNumber减去1。因此,如下所示:

代码语言:javascript
复制
IEnumerable<Statement> statement = bookmarkCollection.AsEnumerable().Select(
bookmark => new Statement()
{
    Title= bookmark.Title,
    PageNumber = bookmark.PageNumber,
    NextPageNumber = ???
});

更新:

我尝试了一些提供的解决方案,但我仍然在使用元组3.5,所以.NET方法已经过时了。Zip操作可以工作(我有模拟3.5的Zip的扩展方法),但它不会为最后一个Bookmark创建语句。最后一个书签的NextPageNumber就是PDF中的页数。

最终更新:

非常感谢大家。在您的帮助下,我能够让它正常工作。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-05-23 04:13:02

下面是一个帮助器函数,它将一个序列映射为一个配对序列,其中每个配对都是每个项目与其后面的项目配对。

代码语言:javascript
复制
public static IEnumerable<Tuple<T, T>> WithNext<T>(this IEnumerable<T> source)
{
    using (var iterator = source.GetEnumerator())
    {
        if(!iterator.MoveNext())
            yield break;

        T previous = iterator.Current;
        while (iterator.MoveNext())
        {
            yield return Tuple.Create(previous, iterator.Current);
            previous = iterator.Current;
        }

        yield return Tuple.Create(previous, default(T));
    }
}

现在您可以执行以下操作:

代码语言:javascript
复制
var query = bookmarkCollection.AsEnumerable()
.WithNext()
.Select(pair => new Statement(){
    Title= pair.Item1.Title,
    PageNumber = pair.Item1.PageNumber,
    NextPageNumber = pair.Item2.PageNumber - 1, //note you'll need to null check for the last item
});
票数 4
EN

Stack Overflow用户

发布于 2013-05-23 04:11:32

使用for循环可能会更好,但是如果你真的很喜欢linq,你可以用.Zip拼凑一些东西:

代码语言:javascript
复制
var strings = new[] { "one", "two", "three", "four", "five" };

var result = strings.Zip(
    strings.Skip(1).Concat(Enumerable.Repeat("last", 1)), 
    (a, b) => new { a, b }
);

结果

代码语言:javascript
复制
one   two 
two   three 
three four 
four  five 
five  last 
票数 2
EN

Stack Overflow用户

发布于 2013-05-23 04:19:08

代码语言:javascript
复制
var bc = bookmarkCollection.AsEnumerable();
IEnumerable<Statement> statement = bc.Zip(bc.Skip(1), 
    (b1,b2) => new Statement()
    {
        Title= b1.Title,
        PageNumber = b1.PageNumber,
        NextPageNumber = b2.PageNumber - 1
    });

Servy EDIT:(根据下面的评论):如果您还需要包含最后一项,那么最好使用@的helper方法。

你可以这样做..。

代码语言:javascript
复制
var bc = bookmarkCollection.AsEnumerable();
IEnumerable<Statement> statement = bc.Zip(bc.Skip(1).Concat(new Bookmark[] { null }), 
    (b1,b2) => new Statement()
    {
        Title= b1.Title,
        PageNumber = b1.PageNumber,
        NextPageNumber = b2 == null ? 0 : b2.PageNumber - 1
    });

...however,我最初推荐Zip只是因为它又快又容易--现在它变得有点难以解释了。因此,我建议你使用@Servy的方法,稍微修改一下,包含一个选择器函数:

代码语言:javascript
复制
public static IEnumerable<TResult> WithNext<T, TResult>(this IEnumerable<T> source, Func<T, T, TResult> selector)
{
    using (var e = source.GetEnumerator())
    {
        if (!e.MoveNext()) yield break;

        T previous = e.Current;
        while (e.MoveNext())
        {
            yield return selector(previous, e.Current);
            previous = e.Current;
        }

        yield return selector(previous, default(T));
    }
}

并像这样使用它:

代码语言:javascript
复制
IEnumerable<Statement> statement = bc.WithNext(
   (b1, b2) => new Statement()
   {
       Title = b1.Title,
       PageNumber = b1.PageNumber,
       NextPageNumber = b2 == null ? 0 : b2.PageNumber - 1
   }).ToList();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16700571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档