[英]Working with Lists, Anonymous Types and Suchlike
繼之前的問題之后,我現在有一個匿名類型的集合
[用戶:用戶名(如forename.surname
, UserId ]。
這個“用戶”集合最終需要綁定到一個下拉列表。 這很好,但我需要做的是按姓氏和名字對它們進行排序。 但這由於用戶名格式是 forename.surname 的事實而變得復雜。
在高層次上,這將涉及對字符串進行Split
以分隔名稱組件,然后ToTitleCase()
兩個部分,然后將新值存儲在另一個 object 中的 List 中,然后我可以使用List<T>.OrderBy(...).ThenBy(...)
進行排序List<T>.OrderBy(...).ThenBy(...)
我突然想到,我正在嘗試學習的所有這些花哨的新語法可能包括一種在幾行簡潔代碼中執行此過程的方法。 任何人都可以確認或否認這一點嗎?
謝謝。
編輯 3:
我想我已經破解了它:
var salesusers = (
from s in lstReport
group s by new { s.SalesUserId,s.Username}
into g
select new
{
Username = g.Key.Username.Split('.')[1].ToTitleCase() + " " + g.Key.Username.Split('.')[0].ToTitleCase(),
Surname = g.Key.Username.Split('.')[1].ToTitleCase(),
Forename = g.Key.Username.Split('.')[0].ToTitleCase(),
UserId = g.Key.SalesUserId
}
).OrderBy(a=> a.Surname).ThenBy(a=> a.Forename);
我需要從用戶名中創建單獨的名字和姓氏字段以進行排序,並從用戶名中創建綁定到下拉列表的字段。 這看起來很瘋狂,但效果很好,我現在堅持使用它。 將不勝感激您的意見。
EDIT2:所以我做到了這一點。 現在我想知道語法是否允許我將之前問題中的Group by
操作與這一步結合起來。
var sortedUsers = from u in salesusers
orderby u.UserName.Split('.')[1], u.UserName.Split('.')[0]
select new {UserName = u.UserName.Replace(".", " ").ToTitleCase(), UserId = u.UserId.Value};
有人……?
編輯:我自己設法完成
了
大部分工作,以防萬一有人需要,但在訂購操作期間轉換名稱組件ToTitleCase
證明是困難的。
這個:
var sortedUsers = from u in salesusers
orderby u.UserName.Split('.')[1], u.UserName.Split('.')[0]
select u;
除了
ToTitleCase 之外,似乎可以解決我需要的
ToTitleCase
。 但是,當然可能有一個更快/更簡潔/更優雅的方法,所以我將把它打開一兩天,看看會發生什么;-)
使用 lambdas 而不是表達式語法可以實現更少的代碼
var sorted = salesusers.OrderBy(u => u.UserName.Split('.')[1]).ThenBy(u => u.UserName.Split('.')[0]).ToList();
雖然它的可讀性較差,但一旦你習慣了這種語法,我發現它比表達式語法更容易閱讀。
編輯:編輯 3 的更改
您轉換為 Lambdas 的代碼如下
var salesusers = (l.GroupBy(s => new { SalesUserId = s.SalesUserId, Username = s.Username }).Select(g =>new {
Username = g.Key.Username.Split('.')[1].ToTitleCase() + " " + g.Key.Username.Split('.')[0].ToTitleCase(),
Surname = g.Key.Username.Split('.')[1].ToTitleCase(),
Forename = g.Key.Username.Split('.')[0].ToTitleCase(),
UserId = g.Key.SalesUserId
})).OrderBy(a => a.Surname).ThenBy(a => a.Forename);
唯一的問題是,表達式越大越難閱讀!
另一種讀取更清晰的方法是定義細節 object 而不是使用動態 object。
internal class UserDetails
{
public UserDetails(User u)
{
this.Forename = u.Username.Split('.')[0].ToTitleCase();
this.Surname = u.Username.Split('.')[1].ToTitleCase();
this.UserId = u.SalesUserId;
this.Username = u.Username;
}
public string Username { get; set; }
public string Surname { get; set; }
public string Forename { get; set; }
public int UserId { get; set; }
}
那么你可以做
var salesusers = (l.GroupBy(s => new { SalesUserId = s.SalesUserId, Username = s.Username })
.OrderBy(u => u.Username.Split('.')[1].ToTitleCase())
.ThenBy(u => u.Username.Split('.')[0].ToTitleCase())
.Select(g => new UserDetails(g)));
但這是我不確定你想要的更多代碼。
最新編輯:
您的代碼不需要 group by 語句,因此您可以通過這樣做來減少它
var salesusers = (
from s in l
select new
{
Username = s.Username.Split('.')[1].ToTitleCase() + " " + s.Username.Split('.')[0].ToTitleCase(),
Surname = s.Username.Split('.')[1].ToTitleCase(),
Forename = s.Username.Split('.')[0].ToTitleCase(),
UserId = s.SalesUserId
}
).OrderBy(a => a.Surname).ThenBy(a => a.Forename);
或者使用 Lambdas 變成
var salesusers = l.Select(g =>new {
Username = g.Username.Split('.')[1].ToTitleCase() + " " + g.Username.Split('.')[0].ToTitleCase(),
Surname = g.Username.Split('.')[1].ToTitleCase(),
Forename = g.Username.Split('.')[0].ToTitleCase(),
UserId = g.SalesUserId
}).OrderBy(a => a.Surname).ThenBy(a => a.Forename);
除此之外,我可以看到進一步減少該調用的唯一方法是使用上面定義的 class ,這並不是說它不能完成! 但我看不到怎么做!
HTH
OneShot
這是我想出的最終解決方案 - 它排序、 ToTitleCase
和格式。 如果我自己這么說,那就太漂亮了。 花了我一上午的時間:-(
var salesusers = (
from s in lstReport
group s by new { s.SalesUserId,s.Username}
into g
select new
{
Username = g.Key.Username.Split('.')[1].ToTitleCase() + " " + g.Key.Username.Split('.')[0].ToTitleCase(),
Surname = g.Key.Username.Split('.')[1].ToTitleCase(),
Forename = g.Key.Username.Split('.')[0].ToTitleCase(),
UserId = g.Key.SalesUserId
}
).OrderBy(a=> a.Surname).ThenBy(a=> a.Forename);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.