在foreach循环中使用多个数据项

时间:2016-06-27 09:46:00

标签: c# variables foreach text-files

我的数据项为:

Dictionary<int, Tuple<int, int>> tPapers = eAuthor.GetPapersBetweenYears(year, year + 1);  
List<int> tCoAuthors = eAuthor.GetCoAuthorsBetweenYears(year, year + 1);  
List<int> tVenues = eAuthor.GetVenuesBetweenYears(year, year + 1);  

我必须将所有这些数据项,即tPaperstCoAuthorstVenues写入文本文件。我试过:

foreach (var kvpaper in tPapers)
{
   // Key is Paper_ID, Item1 is Paper_Category, Item2 is Year
   twObjClus.WriteLine("PaperID: {0}, PaperCategory: {1}, Year: {2}",  
                       kvpaper.Key, kvpaper.Value.Item1, kvpaper.Value.Item2);
}  

而我希望将此表单中的输出写为:

  

Paper_ID:1,Paper_Category:3,CoAutohr_ID:34,Venue_ID:23,年份:   2005

如何在单个foreach()循环中使用所有这些数据项,或者为每个数据项使用单独的循环?

1 个答案:

答案 0 :(得分:2)

您现在没有可以解决问题的工具。您的方法GetCoAuthorsBetweenYearsGetVenuesBetweenYears根本不会返回必要的信息。

为什么呢?那么,如何将GetCoAuthorsBetweenYears返回的任何给定记录与Paper_Id相关联?此方法只返回CoAuthors中存储的所有eAuthors。您需要的是具有以下签名之一的方法:

 List<Tuple<int, int>> GetDocumentsAndCoAuthorsBetweenYears(int lower, int upper) //Tuple.Value1 stores Paper_Id and Tuple.Value2 stores CoAuthor_ID.

 List<int> GetCoAuthorsByDocumentBetweenYears(int documentId, int lower, int upper)

现在,在这两种情况下,您都可以将CoAuthor_ID信息与Paper_ID相关联。与场地相同。

好的,但是如果你可以修改这些方法,那么为什么我们这样做呢?是什么阻止您实施以下内容:

IEnumerable<PaperInfo> GetPaperInfoBetweenYears(int lower, int upper);

PaperInfo的位置:

class PaperInfo
{
    public int Paper_ID { get; set; }
    public int CoAuthor_ID { get; set; }
    public int Paper_Category { get; set; }
    public int Venue_ID { get; set; }
}

现在您只需打印IEnumerable<PaperInfo>

即可
var papers = GetAllPaperInfoBetweenYears(year, year + 1);
var printedInfo = string.Join(Environment.NewLine,
                             papers.Select(p => string.Format("{0} {1} {2} {3}", p.Paper_ID, p.Paper_Category, p.CoAuthor_ID, p.Venue_ID));

更新根据您的意见,我举了一个小例子:

 public class Author
 {
     public int Paper_ID { get; set; }
     public int CoAuthor_ID { get; set; }
     public int Venue_ID { get; set; }
     public int Paper_Category { get; set; }
     public int Year { get; }
     public int Publisher_ID { get; }
     //etc.
 }

 //bring all info from database   
 IEnumerable<Author> eAuthors = GetAllInfoFromDB();

 //Now filter and project what you need
 public static IEnumerable<PaperInfo> GetGetPaperInfoBetweenYears(this List<Author> eAuthors, int lower, int upper)
 {
     return from eAuthor in eAuthors
            where (eAuthor.Year >= lower && eAuthor.Year < upper)
            select new PaperInfo() { Paper_ID = eAuthor.Paper_ID, CoAuthor_ID = eAuthor.CoAuthor_ID, Paper_Category = eAuthor.Paper_Category, Venue_ID = eAuthor.Venue_ID };
 }

当然,您甚至可以不使用PaperInfo,只需按年过滤并投影存储在eAuthorInfo中的所有信息:

public static IEnumerable<PaperInfo> GetGetPaperInfoBetweenYears(this List<Author> eAuthors, int lower, int upper)
 {
     return from eAuthor in eAuthors
            where (eAuthor.Year >= lower && eAuthor.Year < upper)
            select eAuthor;
 }

而且,和以前一样,只需打印出您需要的信息:

var printedInfo = string.Join(Environment.NewLine,
                             papers.Select(p => string.Format("{0} {1} {2} {3}", p.Paper_ID, p.Paper_Category, p.CoAuthor_ID, p.Venue_ID)); //no year, publisher, etc. info

这就是我这样做的方式,预测非常有用,但是当你拥有很多这些预测并且你不能使用匿名类型时,这是很痛苦的。它使你必须为每个投影实现一个类型。