使用Linq获取元组列表

时间:2014-04-09 11:25:03

标签: c# linq

我有一个与时间相关的时间相关的列表以时间点为中心。例如。每个对象 PriceAtTimeX包含有关苹果价格,特定时间点X的禁令价格的信息。

那些我想使用linq转换为JSON,更强以时间轴为中心的格式。例如。一个BananaPrices对象,它基本上由[date,value]列表组成。

具体出发点PriceAtTimeX-class

public class PricesAtTimeX
{
    public int ID { get; set; }
    public DateTime Date { get; set; }
    public int BananaPrice{ get; set; }
    public int ApplePrice{ get; set; }
}

我希望从中得到什么:

[
    {
        "key": "BananaPrices",
        "values": [[date1, bananaPrice1], [date2, bananaPrice2] ... ],
    },
    {
        "key": "ApplePrices",
        "values": [[date1, applePrice1], [date2, applePrice2] ... ],
    }
]

我的问题是:如何获取Linq 的(int,int)列表?


我的第一次尝试是定义一个可用于shell数据的类:

public class dataLine
{
    public string key { get; set; }
    // first tuple-int would be date converted to javascript datetime
    public List<Tuple<int, int>> values { get; set; }
}

..然后尝试用Linq填充它:

var result = from x in db.Prices
             select new List<dataLine>
             {
                 new dataLine() {
                     key = "ApplePrices",
                     values = ???
                 }
             };
return Json(result, JsonRequestBehavior.AllowGet);

另一种方法是将所有值打包到单独的列表中。

var xValues = from x in db.Prices select new List<DateTime>() { x.Date };
var yBananas = from x in db.Prices select new List<int>() { x.BananaPrice};
var yApples = from x in db.Prices select new List<int>() { x.ApplePrice};

..然后使用.Zip方法将每个价格列表与日期列表合并

public List<Tuple<int, int>> TupleMe(List<int> list1, List<int> list2)
{
    return list1.Zip(list2, Tuple.Create).ToList();
}

我会感谢任何建议,提示或想法!

2 个答案:

答案 0 :(得分:1)

一个简单的Select并使用object[]应该做你想要的。

通常您会使用自定义类型,KeyValuePairTupleDateBanana - / ApplePrice组合在一起(对于类型安全),但是既然你要创建一个JSON字符串,那么使用匿名类型和简单的object[]是最简单的方法。

var items = new []
{
    new PricesAtTimeX
    {
        ID = 1,
        Date = DateTime.Now.AddDays(-3),
        ApplePrice = 10,
        BananaPrice = 20
    },
    new PricesAtTimeX
    {
        ID = 1,
        Date = DateTime.Now.AddDays(-2),
        ApplePrice = 12,
        BananaPrice = 20
    },
    new PricesAtTimeX
    {
        ID = 1,
        Date = DateTime.Now.AddDays(-1),
        ApplePrice = 14,
        BananaPrice = 10
    },
    new PricesAtTimeX
    {
        ID = 1,
        Date = DateTime.Now,
        ApplePrice = 17,
        BananaPrice = 7
    },
};

// maybe cache 'items' if you're running LINQ against a database
// and if you're not wanting to hit the database multiple times.
var result = new[]
{
    new 
    {
        key = "BananaPrices",
        values = items.Select(i => new object[]{i.Date, i.BananaPrice})
    },
    new 
    {
        key = "ApplePrices",
        values = items.Select(i => new object[]{i.Date, i.ApplePrice})
    },
};

var json = JsonConvert.SerializeObject(result);
现在

json(为便于阅读而格式化):

[
 {"key":"BananaPrices","values":[["2014-04-06T13:39:01.109062+02:00",20],["2014-04-07T13:39:01.109062+02:00",20],["2014-04-08T13:39:01.109062+02:00",10],["2014-04-09T13:39:01.109062+02:00", 7]]},
 {"key":"ApplePrices" ,"values":[["2014-04-06T13:39:01.109062+02:00",10],["2014-04-07T13:39:01.109062+02:00",12],["2014-04-08T13:39:01.109062+02:00",14],["2014-04-09T13:39:01.109062+02:00",17]]}
]

答案 1 :(得分:1)

尝试使用let分隔子查询中的查询逻辑并将其应用于结果,以获取示例:

var result = from x in db.Prices
             let t = (from p in db.Prices select new { x.Date, x.BananaPrice, x.ApplePrice }
             select new List<dataLine>
             {
                 new dataLine() {
                     key = "ApplePrices",
                     values = t1.Select(t => Tuple.Create(t.Date, t.BananaPrice))
                 }
             };