【问题标题】:Convert object[,] to string[,]?将 object[,] 转换为 string[,]?
【发布时间】:2013-04-24 06:02:41
【问题描述】:

如何将object[,] 转换为string[,]

Object[,] myObjects= // sth
string[,] myString = // ?!? Array.ConvertAll(myObjects, s => (string)s) // this doesn't work

任何建议表示赞赏。

编辑:当然,循环解决方案显然可以做到这一点,但我设想的是在代码和性能方面更优雅的解决方案。

EDIT2:object[,] 当然包含 strings(和数字,但现在这无关紧要)。

【问题讨论】:

  • 您是否真的要转换为string[,]string[]?您的问题不一致。
  • 我假设两个嵌套循环是不可能的?
  • 一些关于为什么多维数组糟糕的细节stackoverflow.com/q/275073/659190,我很想转换成IList<IList<>>
  • 多维数组不是集合,除了循环(或通过黑魔法转换)之外什么都做不了。如果Object[,] 实际包含字符串,为什么它不是string[,]
  • 请注意,每种 LINQ 查询/扩展方法(和类似方法)都只是一种美丽的方式来执行 RAW FOR 循环。您可能根本不会获得任何性能提升。

标签: c#


【解决方案1】:

这应该是最简单和最快的方法之一,假设src 数组中的每个元素都可以转换为dst 数组类型。

object[,] src = new object[,]
{
    {"foo", "bar"},
    {"spam", "eggs"},
};

string[,] dest = new string[src.GetLength(0), src.GetLength(1)];
Array.Copy(src, dest, src.Length);

【讨论】:

  • @ta.speot.is :这是真的,所以可能的技巧是用 null 填充其余部分,然后复制到该区域。还是你有更好的主意?
  • @Paolo Moretti:很好的解决方案。
  • @WiiMaxx:你用了什么,doubles?
  • @HeinrichStack 我刚刚将"eggs" 更改为5
【解决方案2】:

鉴于其他答案,为二维数组编写自己的 ConvertAll 方法真的很容易:

public static TOutput[,] ConvertAll<TInput, TOutput>(TInput[,] array, Func<TInput, TOutput> converter)
{
    var result = new TOutput[array.GetLength(0), array.GetLength(1)];
    for (int i = 0; i < array.GetLength(0); ++i)
        for (int j = 0; j < array.GetLength(1); ++j)
            result[i, j] = converter(array[i, j]);

    return result;
}

仅仅因为 .NET 的作者不想包含这个方法,所以没有必要完全放弃。自己写很简单。

(如果您愿意,可以将其设为扩展方法。)

在 cmets 之后编辑:如果你真的想处理下限(在某个维度上)不为零的数组,它是这样的:

public static TOutput[,] ConvertAll<TInput, TOutput>(TInput[,] array, Func<TInput, TOutput> converter)
{
    int xMin = array.GetLowerBound(0);
    int xLen = array.GetLength(0);
    int yMin = array.GetLowerBound(1);
    int yLen = array.GetLength(1);
    var result = (TOutput[,])Array.CreateInstance(typeof(TOutput), new[] { xLen, yLen, }, new[] { xMin, yMin, });
    for (int x = xMin; x < xMin + xLen; ++x)
        for (int y = yMin; y < yMin + yLen; ++y)
            result[x, y] = converter(array[x, y]);

    return result;
}

【讨论】:

  • @ta.speot.is 我隐含地假设二维数组是使用通常的 C# 语法创建的。当然,我知道可以创建这样的数组:(object[,])Array.CreateInstance(typeof(object), new[] { 10, 20, }, new[] { -3, -7, });,但谁来做呢?你知道,这个问题被标记为 C#。我应该包含处理这种不太可能的情况的代码吗?
  • 这个问题被标记为 C#,你知道(object[,])Array.CreateInstance(typeof(object), new[] { 10, 20, }, new[] { -3, -7, }); 是用什么语言写的?
  • @ta.speot.is 提供更好的解决方案
  • @ta.speot.is 好的,我包含了非零下限的案例。并不是说我认为任何 C# 开发人员都会使用它。
【解决方案3】:
Object[,] myObjects = new Object[3, 2] { { 1, 2 }, { 3, 4 },
                                        { 5, 6 } };

string[,] myString = new string[3, 2];

for (int i = myObjects.GetLowerBound(0); i < myObjects.GetUpperBound(0); i++)
{
     for (int j = myObjects.GetLowerBound(1); j < myObjects.GetUpperBound(1); j++)
     {
          myString[i, j] = myObjects[i, j].ToString();
     }
}

foreach (var item in myString)
{
    Console.WriteLine("{0} - {1}", item.GetType(), item);
}

输出将是;

System.String - 1
System.String - 2
System.String - 3
System.String - 4
System.String - 5
System.String - 6

【讨论】:

  • @Soner Gönül : 10 倍,但是我在代码和性能方面设想了一个更优雅的解决方案。这显然会做到。也是。
  • @HeinrichStack 我研究了多维数组的这种类型的转换,但找不到更好的方法。
  • @ta.speot.is 来自 Array.CreateInstance 文章:>通常,.NET Framework 类库和许多编程语言不处理非零下限。
  • @Johnbot 我只是问了一个问题,“如果数组的下界不是 0 怎么办”。
【解决方案4】:

你可以这样分配空间

string[,] myString = new string[myObjects.GetLength(0),myObjects.GetLength(1)];

然后一些循环应该可以正常工作,如下所示:

for(int k=0;k < myObjects.GetLength(0);k++)
    for(int l=0;l < myObjects.GetLength(1);l++)
        myString[k,l] = myObjects[k,l].ToString();

【讨论】:

  • @HeinrichStack,这很好,假设ToString 提供了您需要的转换。对于许多不覆盖ToString() 的类,大括号中的类型名称不太有用。但是,您不能指望自动为您定义“有用”,因为它是上下文相关的。
  • 你没有实例化myString
  • @Jodrell - 我也没有为 myObjects 赋值,我假设还有其他代码,这只是一个 sn-p,但你说得有道理。
  • @Hogan 10x,但是我正在设想一个在代码和性能方面更优雅的解决方案。这显然会做到。也是。
猜你喜欢
  • 2018-07-16
  • 1970-01-01
  • 2013-05-24
  • 2014-01-29
  • 2014-05-16
  • 2015-11-21
  • 2011-03-08
  • 2015-01-10
  • 2019-06-20
相关资源
最近更新 更多