2013-05-31 80 views
2

我正在研究一個需要顯示高於平均收入的人員列表的項目。源數據是List<IncomeData>id是人的唯一ID):如何在消息框中顯示列表中的項目?

public struct IncomeData 
{ 
    public string id; 
    public double household; 
    public income; 
} 

public double belowAverage = 0, total, belowAveragePercent; 

IncomeData surveyStruct; 
List<IncomeData> surveyList = new List<IncomeData>(); 
List<string> aboveAverage = new List<string>(); 

這是我如何判斷一個人有平均收入以上。如果一個人平均收入之上,我從surveyStruct的臨時實例添加idincome爲字符串值的高於平均水平的名單:

//Determine poverty. 
if (surveyStruct.income - 3480 * surveyStruct.household <= 6730) 
{ 
    belowAverage += 1; 
} 
else if (surveyStruct.income - 3480 * surveyStruct.household >= 6730) 
{ 
    aboveAverage.Add(surveyStruct.id); 
    aboveAverage.Add(surveyStruct.income.ToString()); 
} 

這裏是顯示所需信息的消息中碼框。 (該aboveAverage列表在這裏添加了。)

private void reportsToolStripMenuItem_Click(object sender, EventArgs e) 
{ 
    //Display reports 1, 2, and 3. 
    MessageBox.Show("Your Entry:\nID Code: " + surveyStruct.id + 
     "\nHousehold: " + surveyStruct.household.ToString() + 
     " people\nIncome: " + surveyStruct.income.ToString("C") + 
     "\n\nPeople Above Average:\n" + aboveAverage + 
     "\n\nAnd " + belowAveragePercent + "% of people are below average."); 
    } 

現在,這裏的問題:,而不是在消息框中的值的看到一個名單,我看到System.Collections.Generic.List ` 1[System.String],其中ID和上述平均人的收入應該是。有人可以告訴我我做錯了什麼,以及如何在消息框中顯示列表值?

回答

0

StringBuilder的是一個選擇:

StringBuilder aboveAverage = new StringBuilder(); 

    //Determine poverty. 
    if (surveyStruct.income - 3480 * surveyStruct.household <= 6730) 
    { 
     belowAverage += 1; 
    } 
    else if (surveyStruct.income - 3480 * surveyStruct.household >= 6730) 
    { 
     aboveAverage.Append(string.Format("id: %s, income: %s\n", 
       surveyStruct.id, surveyStruct.income.ToString()); 
    } 

而且你會需要一個ToString()的字符串生成器,像這樣:

MessageBox.Show("Your Entry:\nID Code: " + surveyStruct.id + "\nHousehold: " + surveyStruct.household.ToString() + " people\nIncome: " + surveyStruct.income.ToString("C") + "\n\nPeople Above Average:\n" + aboveAverage.ToString() + "\n\nAnd " + belowAveragePercent + "% of people are below average."); 

你可以做,如果你離開aboveAverage,因爲它與加盟一個列表,如下所示:

string.Join(aboveAverage,Environment.NewLine); 

在您當前的代碼中 - 但看起來不那麼好。

你也可以用Linq來做,你想看到嗎?

好吧,這裏是一個性感的一個行版本:(所有的問題應該有一個行LINQ答案):

(使用的和縮進不計,他們只是爲了讓代碼更易讀!)

using NL = Environment.NewLine; 
     
string indent = "    "; 

MessageBox.Show(
    "Your Entry:" + NL + 
    "ID Code: " + surveyStruct.id + NL + 
    "Household: " + surveyStruct.household.ToString() + " people" + NL + 
    "Income: " + surveyStruct.income.ToString("C") + NL + NL + 
    "People Above Average:" + NL + 
    indent + string.Join(NL+indent, 
          surveyList.Where(s => (s.income - 3480) * s.household >= 6730) 
            .Select(s => "ID: "+s.id+" $"+s.income.ToString).ToArray()) + NL + 
     "And " + (surveyList.Where(s => ((s.income - 3480) * s.household) <= 6730).Count()/surveyList.Count()) * 100 + "% of people are below average."); 
+0

@Hogan難道是不同的,如果我使用LINQ的? –

+0

@ chotto-motto - 只有一行! – Hogan

0

首先,使上述平均值爲List<IncomeData>,並將匹配的IncomeDatas添加到該列表中。

然後,你需要定義一個ToString爲您定製的結構,這樣的事情:

public override void string ToString() 
{ 
    return string.Format("The id is {0}, the household is {1} and the income is {2}.", id, household, income); 
} 

然後,在你的MessageBox.Show呼叫時,您需要更換aboveAverage

aboveAverage.Aggregate((a,b) => a.ToString() + Enviroment.NewLine + b.ToString()) 

應該讓它顯示正確。

對不起格式化,我在手機上。

0

在問題結束時,您問:如何在消息框中顯示List<IncomeData>

因此,您的問題的核心是將您的值列表轉換爲一個字符串,以便您可以將該字符串作爲參數傳遞給MessageBox.Show()

The LINQ擴展方法Enumerable.Aggregate()爲這個問題提供了一個理想的解決方案。說你List<IncomeData>看起來是這樣的(我略去了對household場):

var incomes = new List<IncomeData>() { 
    new IncomeData("abc0123", 15500), 
    new IncomeData("def4567", 12300), 
    new IncomeData("ghi8901", 17100) 
}; 

下面的LINQ查詢轉換將是List<IncomeData>string

string message = incomes. 
    Select(inc => inc.ToString()). 
    Aggregate((buffer, next) => buffer + "\n" + next.ToString()); 

爲了消除需要撥打Select(),您可以改爲使用Enumerable.Aggregate()的雙參數版本。這種方法還允許您指定一個標題爲您的累加器的種子值:

string message2 = incomes. 
    Aggregate(
     "Income data per person:", 
     (buffer, next) => buffer + "\n" + next.ToString()); 

這相當於在參數類型已作出以下明確:

string message = incomes. 
    Aggregate<IncomeData, string>(
     "Income data per person:", 
     (string buffer, IncomeData next) => buffer + "\n" + next.ToString()); 

見以下(和online demo)爲完整的工作示例,其前面是其預期輸出。

期望輸出

Income data per person: 
Id: abc0123, Income:15500 
Id: def4567, Income:12300 
Id: ghi8901, Income:17100 

示範項目

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace LinqAggregateDemo 
{ 
    public class Program 
    { 

     public static void Main(string[] args) 
     {    
      var incomes = new List<IncomeData>() { 
       new IncomeData("abc0123", 15500), 
       new IncomeData("def4567", 12300), 
       new IncomeData("ghi8901", 17100) 
      }; 

      string message = incomes. 
       Select(inc => inc.ToString()). 
       Aggregate((buffer, next) => buffer + "\n" + next.ToString()); 

      Console.WriteLine("Income data per person:\n" + message); 
     } 

     public struct IncomeData 
     { 
      public readonly string Id; 
      public readonly int Income; 

      public IncomeData(string id, int income) 
      { 
       this.Id = id; 
       this.Income = income; 
      } 

      public override string ToString() 
      { 
       return String.Format(
        "Id: {0}, Income:{1}", 
        this.Id, 
        this.Income); 
      } 
     } 
    } 
} 
相關問題