January 7, 2014

列舉資料flattening實作

有一需求要把如下列舉物件資料做flattening後顯示為Pete,Chen,09xx123456;Claire,Chang,09xx234567;Pudding,Chen,09xx345678;Jelly,Chen,09xx4567891。也就是單一筆資料內的屬性是以逗號串接起來,而每筆資料再以分號串接起來。
private IEnumerable<User> Users
{
    get
    {
        yield return new User() { FirstName = "Pete", LastName = "Chen", PhoneNumber = "09xx123456" };
        yield return new User() { FirstName = "Claire", LastName = "Chang", PhoneNumber = "09xx234567" };
        yield return new User() { FirstName = "Pudding", LastName = "Chen", PhoneNumber = "09xx345678" };
        yield return new User() { FirstName = "Jelly", LastName = "Chen", PhoneNumber = "09xx456789" };
    }
}

public class User
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string PhoneNumber { get; set; }
}

要達到上述需求,比較苦力一點的作法就是自已寫一個method,將列舉物件資料傳入後以迴圈方式取出資料後串接,但如果要串接的列舉物件資料越多,就會需要更多相對應的method來處理。另一種方式則是利用LINQ提供的projection功能搭配string.Join來達到串接的效果。

首先我們使用LINQ提供的Select方法來將列舉資料中的物件project成單一字串。
IEnumerable<string> projected = this.Users.Select(c => string.Format("{0},{1},{2}", c.FirstName, c.LastName, c.PhoneNumber));
Assert.AreEqual("Pete,Chen,09xx123456", projected.ElementAt(0));
Assert.AreEqual("Claire,Chang,09xx234567", projected.ElementAt(1));
Assert.AreEqual("Pudding,Chen,09xx345678", projected.ElementAt(2));
Assert.AreEqual("Jelly,Chen,09xx456789", projected.ElementAt(3));
project後,列舉資料的型別就變為string了。接下來只要使用string.Join將列舉資料以分號串接起來即可完成實作。
string joined = string.Join(";", projected);
Assert.AreEqual("Pete,Chen,09xx123456;Claire,Chang,09xx234567;Pudding,Chen,09xx345678;Jelly,Chen,09xx456789", joined);
當然也可以用一行程式碼來完成。
string joined = string.Join(";", this.Users.Select(c => string.Format("{0},{1},{2}", c.FirstName, c.LastName, c.PhoneNumber)));
Assert.AreEqual("Pete,Chen,09xx123456;Claire,Chang,09xx234567;Pudding,Chen,09xx345678;Jelly,Chen,09xx456789", joined);

No comments: