我有一个称为CalculatePopularityScore
的方法。它存在于Story
对象上。 Story
对象具有一个字段,该字段是Comment对象的ICollection。
public virtual ICollection<Comment> Comments { get; set; }
Comment
对象具有Reply
对象的另一个集合。
我的方法着眼于故事,循环浏览与该故事相关的评论,如果该故事的评论得到回复,则将总数加起来。这样,再加上其他一些领域,就使我有了一个非常(而且我对此很强调)非常简单的故事受欢迎度算法。
public double CalculateStoryPopularityScore()
{
if (Comments == null) throw new ArgumentException("Comments can't be null");
if (Comments.Count < 0) throw new ArgumentException("Comments can't be less than zero.");
int ReplyCountSum = 0;
double ReplyScore;
double CommentScore;
double InsightfulVoteScore;
double UsefulVoteScore;
double viewCount;
foreach (var comment in Comments)
{
int replyCount;
if (comment.Replies == null)
{
throw new ArgumentNullException("Replies cannot be null");
}
if (comment.Replies.Count() == 0)
{
replyCount = 0;
} else
{
replyCount = comment.Replies.Count();
}
ReplyCountSum += replyCount;
}
ReplyScore = ReplyCountSum * 4;
CommentScore = Comments.Count() * 4;
InsightfulVoteScore = InsightFulVoteCount * 3;
UsefulVoteScore = UsefulVoteCount * 2;
viewCount = ViewCount;
double PopularityScore = CommentScore + ReplyScore + InsightfulVoteScore + + UsefulVoteScore + viewCount;
return PopularityScore;
}
这似乎很好。现在,我想做的就是采用这种方法,并将其应用于多个故事(即列表)。
我目前已编写此方法。它尚未实现另一个循环来浏览对故事的评论集合的答复。我知道嵌套循环被认为是不好而且很慢。查看故事列表,然后查看每个故事中的评论列表,将这些答复加起来,然后计算故事的受欢迎程度得分,最有效的方法是什么?
public void CalculateStoryPopularityScore(List<Story> stories)
{
if (stories == null) throw new ArgumentException("Stories can't be null");
double CommentScore;
double InsightfulVoteScore;
double UsefulVoteScore;
double PopularityScore;
double ViewCount;
foreach (var story in stories)
{
CommentScore = story.Comments.Count() * 4;
InsightfulVoteScore = story.InsightFulVoteCount * 3;
UsefulVoteScore = story.UsefulVoteCount * 2;
ViewCount = story.ViewCount;
PopularityScore = CommentScore + InsightfulVoteScore + UsefulVoteScore + ViewCount;
story.PopularityScore = PopularityScore;
}
}
答案 0 :(得分:0)
使用SelectMany
var commentCount = story.Comments.Count();
// count all replies to all comments for a story
var replyCountSum = story.Comments
.SelectMany(c => c.Replies)
.Count();
应用于故事集:
stories.Select(s => new
{
Story = s,
CommentCount = s.Comments.Count(),
ReplyCount = s.Comments.SelectMany(c => c.Replies).Count(),
});
答案 1 :(得分:0)
除非我丢失了某些内容,否则您使用单独方法计算的所有分数都可以写为Story
类的公共只读(计算)属性。可以通过使用SelectMany
(用于将列表的列表扁平化为单个列表)然后获得Count
属性来获得回复计数:
public class Story
{
public List<Comment> Comments { get; set; }
public int InsightFulVoteCount { get; set; }
public int UsefulVoteCount { get; set; }
public int ViewCount { get; set; }
public int PopularityScore
{
get
{
return
(Comments?.Count ?? 0) * 4 +
(Comments?.SelectMany(comment => comment.Replies).Count() ?? 0) * 4 +
InsightFulVoteCount * 3 +
UsefulVoteCount * 2 +
ViewCount;
}
}
}
public class Comment
{
public List<string> Replies { get; set; }
}
如果您不熟悉null-conditional运算符(?.
),则在访问右操作数(属性)之前,如果左操作数(对象)为null,它将返回null
或对象的方法)。如果左侧不为null,则返回属性/方法值。
然后null-coalescing operator(??
)评估左操作数(这是属性或方法访问的结果),如果为空,则返回右操作数('0'
就我们而言)。
基本上,这简化了代码。您不必这样做:
var score = 0;
if (Comments != null) score = Comments.Count;
您可以这样做:
var score = Comments?.Count ?? 0;