如何将int[]转换为short[]?

3
int[] iBuf = new int[2];
iBuf[0] = 1;
iBuf[1] = 2;

short[] sBuf = new short[2];
Buffer.BlockCopy(iBuf, 0, sBuf, 0, 2);

result  
iBuf[0] = 1  
sBuf[0] = 1  
iBuf[1] = 2  
sBuf[1] = 0  

My desired result  
iBuf[0] = 1  
sBuf[0] = 1  
iBuf[1] = 2  
sBuf[1] = 2  

我的结果与我想要的不同。
有没有一种方法可以在不使用循环的情况下进行转换?


1
简单的答案是否定的 - int使用4个字节,shorts使用2个字节 - 因此基本上您需要复制交替的字节对。下面给出的答案是有效的 - 但在方法的内部,它们将使用循环。根据数组的大小,可能可以使用自己的方法编写更快的解决方案。 - PaulF
2个回答

6
你可以使用Array.ConvertAll方法。
示例:
int[]   iBuf = new int[2];
  ...
short[] sBuf = Array.ConvertAll(iBuf, input => (short) input);

这个方法需要一个输入数组和一个转换器,结果将是你想要的数组。
编辑: 更短的版本是在ConvertAll中使用现有的Convert.ToInt16方法。
int[] iBuf = new int[5];
short[] sBuf = Array.ConvertAll(iBuf, Convert.ToInt16);

那么,ConvertAll是如何工作的呢?让我们来看一下实现方式:
public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array, Converter<TInput, TOutput> converter)
{
    if (array == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
    }

    if (converter == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.converter);
    }

    Contract.Ensures(Contract.Result<TOutput[]>() != null);
    Contract.Ensures(Contract.Result<TOutput[]>().Length == array.Length);
    Contract.EndContractBlock();


    TOutput[] newArray = new TOutput[array.Length];

    for (int i = 0; i < array.Length; i++)
    {
        newArray[i] = converter(array[i]);
    }
    return newArray;
}

回答实际问题... 不,必须涉及循环以将所有值转换。你可以编写自己的程序或者使用已经构建好的方法。

0

int 是 32 位长,short 是 16 位长,所以直接复制数据的方法行不通。

通用的方法是创建一个将 int 转换为 short 的方法:

public IEnumerable<short> IntToShort(IEnumerable<int> iBuf)
{
    foreach (var i in iBuf)
    {
        yield return (short)i;
    }
}

然后使用它:

int[] iBuf = new int[2];
iBuf[0] = 1;
iBuf[1] = 2;

short[] sBuf = IntToShort(iBuf).ToArray();

1
为什么要创建额外的方法,当我可以用一行代码完成呢? - Nino
OP写一个方法的原因是什么,当.NET已经提供了这个功能 - 请参考Milster的答案。 - PaulF
如果他使用的是.NET 2.0或更早版本,那么他能使用LINQ方法吗? - pitersmx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接