我有以下LINQ语句:
IEnumerable<Statement> statement = bookmarkCollection.AsEnumerable().Select(
bookmark => new Statement()
{
Title = bookmark.Title,
PageNumber = bookmark.PageNumber
});语句有另一个名为NextPageNumber的属性,我需要能够填充该属性。NextPageNumber等于下一条记录的PageNumber减去1。因此,如下所示:
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中的页数。
最终更新:
非常感谢大家。在您的帮助下,我能够让它正常工作。
发布于 2013-05-23 04:13:02
下面是一个帮助器函数,它将一个序列映射为一个配对序列,其中每个配对都是每个项目与其后面的项目配对。
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));
}
}现在您可以执行以下操作:
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
});发布于 2013-05-23 04:11:32
使用for循环可能会更好,但是如果你真的很喜欢linq,你可以用.Zip拼凑一些东西:
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 }
);结果
one two
two three
three four
four five
five last 发布于 2013-05-23 04:19:08
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方法。
你可以这样做..。
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的方法,稍微修改一下,包含一个选择器函数:
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));
}
}并像这样使用它:
IEnumerable<Statement> statement = bc.WithNext(
(b1, b2) => new Statement()
{
Title = b1.Title,
PageNumber = b1.PageNumber,
NextPageNumber = b2 == null ? 0 : b2.PageNumber - 1
}).ToList();https://stackoverflow.com/questions/16700571
复制相似问题