C# 更高效、更可读的嵌套循环
我创建了一个算法,它根据与文章属性相关的两个关键字列表来衡量文章列表的相关性 它工作得很好,而且非常高效。。。但这真是一团糟。它的可读性不太好,所以很难辨别出发生了什么 伪代码中的操作如下所示:C# 更高效、更可读的嵌套循环,c#,loops,readability,C#,Loops,Readability,我创建了一个算法,它根据与文章属性相关的两个关键字列表来衡量文章列表的相关性 它工作得很好,而且非常高效。。。但这真是一团糟。它的可读性不太好,所以很难辨别出发生了什么 伪代码中的操作如下所示: 循环浏览名为articles(list) 对于每篇文章,循环浏览角色列表中的每个角色(列表) 检查当前文章是否有任何角色(article.roles=List) 如果是,则循环文章中的每个角色,并尝试将文章中的角色与当前循环中的角色相匹配 如果找到匹配项,则增加物品的重量。如果项目上的角色索引和角色列
- 循环浏览名为articles
(list)
- 对于每篇文章,循环浏览角色列表中的每个角色
(列表)
- 检查当前文章是否有任何角色
(article.roles=List)
- 如果是,则循环文章中的每个角色,并尝试将文章中的角色与当前循环中的角色相匹配
- 如果找到匹配项,则增加物品的重量。如果项目上的角色索引和角色列表中的角色都是索引0(在主位置),请为两个匹配的主项添加额外的权重
- 对主题重复,但对主要匹配没有奖励
foreach
,除非在一个或两个地方使用,因为我需要匹配索引以知道在匹配中添加什么值
private static List<Article> WeighArticles(List<Article> articles, List<string> roles, List<string> topics, List<string> industries)
{
var returnList = new List<Article>();
for (int currentArticle = 0; currentArticle < articles.Count; currentArticle++)
{
for (int currentRole = 0; currentRole < roles.Count; currentRole++)
{
if (articles[currentArticle].Roles != null && articles[currentArticle].Roles.Count > 0)
{
for (int currentArticleRole = 0; currentArticleRole < articles[currentArticle].Roles.Count; currentArticleRole++)
{
if (articles[currentArticle].Roles[currentArticleRole].ToLower() == roles[currentRole].ToLower())
{
if (currentArticleRole == 0 && currentRole == 0)
articles[currentArticle].Weight += 3;
else
articles[currentArticle].Weight += 1;
}
}
}
}
for (int currentTopic = 0; currentTopic < topics.Count; currentTopic++)
{
if (articles[currentArticle].Topics != null && articles[currentArticle].Topics.Count > 0)
{
for (int currentArticleTopic = 0; currentArticleTopic < articles[currentArticle].Topics.Count; currentArticleTopic++)
{
if (articles[currentArticle].Topics[currentArticleTopic].ToLower() == topics[currentTopic].ToLower())
{
articles[currentArticle].Weight += 0.8;
}
}
}
}
returnList.Add(articles[currentArticle]);
}
return returnList;
}
//Article Class stub (unused properties left out)
public class Article
{
public List<string> Roles { get; set; }
public List<string> Topics { get; set; }
public double Weight { get; set; }
}
私有静态列表文章(列表文章、列表角色、列表主题、列表行业)
{
var returnList=新列表();
对于(int currentArticle=0;currentArticle0)
{
对于(int currentArticleRole=0;currentArticleRole0)
{
对于(int currentArticleTopic=0;currentArticleTopic
好的,您的代码中有几个设计缺陷:
1-太程序化了。你需要学会思考如何编写代码来告诉机器“你想要什么”,而不是“怎么做”,这类似于去酒吧,告诉酒保每样东西的确切比例,而不仅仅是要一杯饮料
2-。这意味着要检查文章[x]。角色!=空值
毫无意义
3-在列表上迭代并将每个字符串与其他字符串进行比较也没有意义。改用
4-您正在抓取输入列表中的每一项,并将其输出到新列表中。也是胡说八道。直接返回输入列表或使用inputList.ToList()
总而言之,这里有一种更惯用的C语言编写代码:
private static List<Article> WeighArticles(List<Article> articles, List<string> roles, List<string> topics, List<string> industries)
{
var firstRole = roles.FirstOrDefault();
var firstArticle = articles.FirstOrDefault();
var firstArticleRole = firstArticle.Roles.FirstOrDefault();
if (firstArticleRole != null && firstRole != null &&
firstRole.ToLower() == firstArticleRole.ToLower())
firstArticle.Weight += 3;
var remaining = from a in articles.Skip(1)
from r in roles.Skip(1)
from ar in a.Roles.Skip(1)
where ar.ToLower() == r.ToLower()
select a;
foreach (var article in remaining)
article.Weight += 1;
var hastopics = from a in articles
from t in topics
from at in a.Topics
where at.ToLower() == t.ToLower()
select a;
foreach (var article in hastopics)
article.Weight += .8;
return articles;
}
私有静态列表文章(列表文章、列表角色、列表主题、列表行业)
{
var firstRole=roles.FirstOrDefault();
var firstArticle=articles.FirstOrDefault();
var firstArticleRole=firstArticle.Roles.FirstOrDefault();
if(firstArticleRole!=null&&firstRole!=null&&
firstRole.ToLower()==firstArticleRole.ToLower())
首件。重量+=3;
var剩余=从文章中的a开始。跳过(1)
从角色中的r。跳过(1)
从a.Roles.Skip中的ar(1)
其中ar.ToLower()==r.ToLower()
选择一个;
foreach(剩余的var条款)
物品重量+=1;
var hastopics=来自文章中的
从t到主题
来自a.主题中的at
其中at.ToLower()==t.ToLower()
选择一个;
foreach(hastopics中的var文章)
物品重量+=.8;
归还物品;
}
还有更好的编写方法,例如使用.Take(1)
而不是.FirstOrDefault()
好的,您的代码中有几个设计缺陷:
1-太程序化了。你需要学会思考如何编写代码来告诉机器“你想要什么”,而不是“怎么做”,这类似于去酒吧,告诉酒保每样东西的确切比例,而不仅仅是要一杯饮料
2-。这意味着要检查文章[x]。角色!=空值
毫无意义
3-在列表上迭代并将每个字符串与其他字符串进行比较也没有意义。改用
4-您正在抓取输入列表中的每一项,并将其输出到新列表中。也是胡说八道。直接返回输入列表或使用inputList.ToList()创建新列表
foreach(var article in articles)
{
article.AddWeights(roles);
article.AddWeights(topics);
}
public double Weight { get; private set; } // probably you don't need setter
public void AddWeights(IEnumerable<Role> roles)
{
const double RoleWeight = 1;
const double PrimaryRoleWeight = 3;
if (!roles.Any())
return;
if (Roles == null || !Roles.Any())
return;
var pirmaryRole = roles.First();
var comparison = StringComparison.CurrentCultureIgnoreCase;
if (String.Equals(Roles[0], primaryRole, comparison))
{
Weight += PrimaryRoleWeight;
return;
}
foreach(var role in roles)
if (Roles.Contains(role, StringComparer.CurrentCultureIgnoreCase))
Weight += RoleWeight;
}
public void AddWeights(IEnumerable<Topic> topics)
{
const double TopicWeight = 0.8;
if (Topics == null || !Topics.Any() || !topics.Any())
return;
foreach(var topic in topics)
if (Topics.Contains(topic, StringComparer.CurrentCultureIgnoreCase))
Weight += TopicWeight;
}