C# - 将对象列表转换为包含多个对象属性的数组

Posted

技术标签:

【中文标题】C# - 将对象列表转换为包含多个对象属性的数组【英文标题】:C# - convert a list of objects to an array of multiple of the object's properties 【发布时间】:2021-02-15 22:54:08 【问题描述】:

我有这个 JSON 字符串:


  "countries": [
    
      "countryCode": "AR",
      "country": "Argentina"
    ,

      "countryCode": "BR",
      "country": "Brazil"
    
  ]

还有这个 Country 类和国家列表:

List<Country> countries  get; set; 
class Country
    
        public string country  get; set; 
        public string countryCode  get; set; 
    

我需要创建一个包含国家代码和名称的二维对象数组:

propVal[0, 0] = "AR";
propVal[0, 1] = "Argentina";
propVal[1, 0] = "BR";
propVal[1, 1] = "Brazil";
.
.
.

现在我正在“手动”遍历国家列表并构建对象数组:

int row = 0;
foreach (Country country in countries)

    propVal[row, 0] = country.countryCode;
    propVal[row, 1] = country.country;
    row++;

远景是有一个通用的方式,适用于其他 JSON,假设有 3 个或更多属性,并产生一个 x 维对象数组。 有没有一种 LINQ 方法可以做到这一点?我知道this 线程,它处理一个对象属性并且LINQ 方法是countries.Select(x=&gt;x.country).ToArray(),但在我的情况下需要多个属性。

感谢您的帮助!

【问题讨论】:

这似乎是一个 X/Y 问题。为什么你需要一个多维数组,而不是一个类(国家)列表 因为生成的多维对象数组会写入Excel表格。 你可以使用反射来做到这一点。但它不会很漂亮......使用DataTable怎么样? 没有内置的 linq 方法来生成多维数组 - 这有一个很好的理由:数组的维数必须在编译时知道 - 所以你不能有一个方法可以返回一个任意维数的数组。方法可以做到这一点的唯一方法是返回 dynamicobject - 这为各种问题打开了大门 - 主要问题是应该是编译时错误的错误被推送到运行时。 正常序列化,然后循环填充二维数组。你也可以喜欢 JObject,但我不会打扰。像往常一样序列化它 【参考方案1】:

如果你真的需要构建一个二维数组,你可以通过这种方式动态排列数据:

var data = new List<Country>

    new Country country = "Brazil", countryCode = "BR",
    new Country country = "Argentina", countryCode = "AR"
;

// declare all the property accessors you want from your type (Country)
// it can be built by reflection
var accessors = new List<Func<Country, string>>

    x => x.country,
    x => x.countryCode
;

// declaring the 2D array,
//   first dimension length is the size of the data (number of countries)
//   second dimension length is the number of fields from the data type (Country)
var propVal = new string[data.Count, accessors.Count];

// projecting each element with each field accessor (cartesian product)
// that is (countries.Count) x (accessors.Count)
// (0,0,"Brazil") (0,1,"BR") (1,0,"Argentina") (1,1,"AR")
var flatenData = data.SelectMany((country, i) => accessors.Select((f, j) => (i, j, field: f(country))));

// filling the 2D array
foreach (var tuple in flatenData)

    propVal[tuple.i, tuple.j] = tuple.field;

如果我们显示二维数组:

// displaying the 2D array
for (var i = 0; i < propVal.GetLength(0); i++)

    for (var j = 0; j < propVal.GetLength(1); j++)
    
        Console.WriteLine($"[i,j] = propVal[i,j]");
    


/*
[0,0] = Brazil
[0,1] = BR
[1,0] = Argentina
[1,1] = AR
*/

【讨论】:

【参考方案2】:

我建议从多维数组切换到数组数组 - 它更容易实现,并且很可能满足您在此任务中的所有需求。

这是您需要做的。假设您有一些具有一堆公共属性的通用类,您希望以这种方式序列化:

    public class A
    
        public string P1 get; set;
        public string P2 get; set;
        public string P3 get; set;
    

您可以像这样获取该类的属性集合:

    var props = typeof(A).GetProperties();

然后,您需要做的就是对您的项目集合进行 LINQ 并获取每个属性的值:

var result = items.Select(item => 
                     props.Select(prop => 
                       prop.GetValue(item)
                           .ToString())
                          .ToArray())
                  .ToArray();

当然,itemsList&lt;A&gt;

就是这样。你有自己的数组。

如果你觉得你确实需要它是一个 2D 数组,那么你必须像 here 那样实现转换。

【讨论】:

以上是关于C# - 将对象列表转换为包含多个对象属性的数组的主要内容,如果未能解决你的问题,请参考以下文章

在c#中将对象列表转换为数组-“x => x.Name”语法是啥意思? [复制]

C#如何将OBJECT转换成数组

如何使用 Newtonsoft.Json 将包含数组数组的 json 对象解析为 C# 中的对象列表?

如何在 C# 中将列表或数组转换为子类型?

如何将具有元素数组的每个对象的对象列表转换为具有子元素作为属性的对象数组

怎样将json数据转换成匿名数组或者泛型对象(c#)