一個可能的解決方案可以是這樣的:
var result =
from c in census_data
group c by c.state into g
join s in state_gdp on g.FirstOrDefault().state equals s.state
orderby s.gdp descending
select new
{
State = g.Key,
Count = g.Count(),
SavingsBalance = g.Average(x => x.savingsBalanceDouble),
GDP = s.gdp
};
var buffer = new StringBuilder();
buffer.AppendLine("#key,name,sum,gdp");
result.ToList().ForEach(item => buffer.AppendLine(String.Format("{0},{1},{2},{3}", item.State, item.Count, item.SavingBalance, item.GDP)));
File.WriteAllText("d:\\temp\\file.csv", buffer.ToString());
您需要更改Enumerable
到IEnumerable
。由於您正在創建一個匿名對象,因此您的解決方案會將匿名對象列表(IEnumerable<anonymous>
)傳輸到您將數據寫入文件的函數中,但無法根據需要格式化輸出。
一個可能的解決辦法是把要寫入文件的字符串緩衝區的線,然後寫的文字一次使用System.IO.File.WriteAllText方法:
// test data
var data = new List<Int32> { 1, 20, 30, 40, 50, 70 };
// create a list of anonymous objects
var result = data.Select (d => new
{
Count = d,
State = String.Format("Item {0}", d),
SavingBalance = d * 10
});
// create the output text buffer
var buffer = new StringBuilder();
// add header line
buffer.AppendLine("#key,name,sum");
// add each result line
result.ToList().ForEach(item => buffer.AppendLine(String.Format("{0},{1},{2}", item.Count, item.State, item.SavingBalance)));
// write to file
File.WriteAllText("d:\\temp\\file.csv", buffer.ToString());
的輸出是:
#key,name,sum
1,Item 1,10
20,Item 20,200
30,Item 30,300
40,Item 40,400
50,Item 50,500
70,Item 70,700
其中@aravol和@StephneKennedy提到的解決方案將是這樣的:
public static class CSVWriter
{
public static void write<T>(this IEnumerable<T> e, string file)
{
using (System.IO.StreamWriter f = new System.IO.StreamWriter(file))
{
foreach (var i in e)
{
f.WriteLine(i);
}
}
}
}
,並可以這樣使用:
result.write<object>(file);
如前所述,這種解決方案的問題是,你不能格式化輸出,因爲你正在使用Object.toString方法,你不能格式化(默認輸出看起來像{ key = value, key = value, ... }
)。
如果您仍想將結果傳輸到另一個方法,則創建一個類型化類併爲每個結果條目創建一個對象(然後傳輸該列表)。一個例子類型的類可以是這樣的:
public class Placeholder
{
public String Name { get; set; }
public Int32 Index { get; set; }
public Double Sum { get; set; }
}
然後改變你的LINQ查詢創建的Placeholder
一個新的對象,而不是匿名對象:
// test data
var data = new List<Int32> { 1, 20, 30, 40, 50, 70 };
var result = data.Select (d => new Placeholder
{
Key = d,
Name = String.Format("Item {0}", d),
Sum = d * 10.0m
}).ToList();
result.write<Placeholder>("d:\\temp\\file.csv");
而且你的擴展方法可以直接使用write(this IEnumerable<Placeholder>...)
或者投射每個對象以使用類屬性:
public static class CSVWriter
{
public static void write<T>(this IEnumerable<T> e, string file)
{
using (System.IO.StreamWriter f = new System.IO.StreamWriter(file))
{
foreach (var i in e)
{
f.WriteLine(((Placeholder)i).Sum);
}
}
}
}
「您的解決方案將無法工作,因爲您無法傳輸匿名對象列表(IEnumera ble)將數據寫入文件的功能。「是的,你可以,我的例子就是這麼做的 - 編譯器足夠聰明,可以接受匿名的T.問題是匿名對象上沒有可用的ToString()來創建所需的輸出。 –
2014-10-18 17:14:20
@StephenKennedy好點,謝謝。我改變了我的答案。 – pasty 2014-10-18 17:17:04
我喜歡你的第一個解決方案。但是我怎樣才能選擇每個條目屬性(狀態,計數,...)?因爲在你的測試數據中只有一個整數列表,但我的數據不是那樣 – dabadaba 2014-10-18 17:25:09