GVKun编程网logo

delphi – 动态数组是否支持非零下限(对于VarArrayCreate兼容性)?(delphi动态数组怎么赋值)

17

如果您想了解delphi–动态数组是否支持非零下限(对于VarArrayCreate兼容性)?的相关知识,那么本文是一篇不可错过的文章,我们将对delphi动态数组怎么赋值进行全面详尽的解释,并且为您

如果您想了解delphi – 动态数组是否支持非零下限(对于VarArrayCreate兼容性)?的相关知识,那么本文是一篇不可错过的文章,我们将对delphi动态数组怎么赋值进行全面详尽的解释,并且为您提供关于arrays – Delphi – Byte数组到字符串、arrays – Delphi中字符串和记录的常量就地数组、arrays – Delphi:TVarRec与varArray的数组、array_map/array_filter/array_walk遍历数组的方式和foreach一样,谁要快一些啊?的有价值的信息。

本文目录一览:

delphi – 动态数组是否支持非零下限(对于VarArrayCreate兼容性)?(delphi动态数组怎么赋值)

delphi – 动态数组是否支持非零下限(对于VarArrayCreate兼容性)?(delphi动态数组怎么赋值)

我将维护并移植到Delphi XE2一堆非常旧的Delphi代码,这些代码充满了 VarArrayCreate个构造,伪造的动态数组的下限不为零.

使用Variant类型的缺点是:

>比原生数组慢很多(代码执行大量复杂的财务计算,因此速度很重要)
>不安全(特别是在偶然使用错误的var …常量时,Variant系统开始进行不需要的转换或舍入)

如果我能使用dynamic arrays,两者都可能没有实际意义.

变体数组的好处是它们可以具有非零下界.

我记得的是动态数组总是以零的下限开始.

这仍然是真的吗?换句话说:动态数组是否可以以不同于零的边界开始?

作为示例,针对特定情况的前/后示例(单维,但代码充满了多维数组,除了varDouble,代码还使用TVarData允许使用的各种其他varXXX数据类型):

function CalculateVector(aSV: TStrings): Variant;
var
  I: Integer;
begin
  Result := VararrayCreate([1,aSV.Count-1],varDouble);
  for I := 1 to aSV.Count-1 do
    Result[I] := CalculateItem(aSV,I);
end;

CalculateItem函数返回Double.界限从1到aSV.Count-1.

当前替换是这样的,交换Result的空间第零元素以改进编译时间检查:

type
  TVector = array of Double;
function CalculateVector(aSV: TStrings): TVector;
var
  I: Integer;
begin
  SetLength(Result,aSV.Count); // lower bound is zero,we start at 1 so we ignore the zeroth element
  for I := 1 to aSV.Count-1 do
    Result[I] := CalculateItem(aSV,I);
end;

解决方法

动态数组的下限始终为0.因此,对于所有动态数组,低(A)等于0.这对于空动态阵列甚至是零也是如此.

从documentation:

Dynamic arrays are always integer-indexed,always starting from 0.

arrays – Delphi – Byte数组到字符串

arrays – Delphi – Byte数组到字符串

在我的Delphi VCL表单应用程序中,我有一个具有TBuff参数的程序(在字节数组之前定义).在此过程中,我必须将参数转换为字符串.

procedure Form1.Convert(Collect: TBuff);
var 
   str: String;
begin
   str := SysUtils.StringOf(Collect);
end;

编译之后,我被警告存在这个编译器错误:

Incompatible types :’System.TArray<System.TByte>’ and ‘TBuff’

解决方法

您遇到的问题是您已经定义了自己的字节数组类型,如下所示:

type
  TBuff = array of Byte;

您的这种私有类型与其他字节数组类型不兼容.大多数使用字节数组的RTL函数使用RTL类型TBytes,它被声明为TArray< Byte>.

你要做的第一件事就是从你的程序中删除TBuff,而不是使用TBytes.如果继续使用TBuff,您会发现所有字节数组代码都存在于自己的贫民窟中,无法与使用TBytes的库功能进行交互.因此,逃离贫民区,并从存在中删除你的TBuff类型.

现在,为了将字节数组转换为字符串,您需要提供编码信息来执行此操作.您选择了StringOf,这些日子应该被视为遗留功能.最好在转换中更明确并使用TEncoding.

例如,如果字节数组是UTF-8,则写入:

str := TEncoding.UTF8.GetString(ByteArray);

如果字节数组是用本地ANSI编码编码的,那么你写:

str := TEncoding.ANSI.GetString(ByteArray);

在您的情况下,使用StringOf表示字节数组是ANSI编码的,因此后一个示例是您所需要的.

arrays – Delphi中字符串和记录的常量就地数组

arrays – Delphi中字符串和记录的常量就地数组

德尔福可以这样吗? (使用动态字符串和记录数组)

type
  TStringArray = array of String;
  TRecArray = array of TMyRecord;

procedure DoSomethingWithStrings(Strings : TStringArray);
procedure DoSomethingWithRecords(Records : TRecArray);
function buildrecord(const Value : String) : TMyRecord;

DoSomethingWithStrings(['hello','world']);
DoSomethingWithRecords([buildrecord('hello'),buildrecord('world')]);

我知道它不会像那样编译.只想问是否有一个技巧可以得到类似的东西.

解决方法

如果您不必更改DoSomethingWith *例程中的数组长度,我建议使用开放数组而不是动态数组,例如像这样:

procedure DoSomethingWithStrings(const Strings: array of string);
var
  i: Integer;
begin
  for i := Low(Strings) to High(Strings) do
    Writeln(Strings[i]);
end;

procedure DoSomethingWithRecords(const Records: array of TMyRecord);
var
  i: Integer;
begin
  for i := Low(Records) to High(Records) do
    Writeln(Records[i].s);
end;

procedure Test;
begin
  DoSomethingWithStrings(['hello','world']);
  DoSomethingWithRecords([buildrecord('hello'),buildrecord('world')]);
end;

请注意参数列表中的字符串数组 – 而不是TStringArray!有关详细信息,请参阅文章“Open array parameters and array of const”,尤其是有关“混淆”的部分.

arrays – Delphi:TVarRec与varArray的数组

arrays – Delphi:TVarRec与varArray的数组

我想使用各种类型的开放数组(例如:[‘string’,12,123.21]).在我搜索期间,我发现了两种方法.一个是tvarRec数组,另一个是vararray.我认为tvarRec数组是最好的选择,因为它似乎更轻量级,另一方面vararray已经有一些我必须创建的实现,如果我想使用tvarRec数组.

有人对这两种使用方式有什么看法吗?

解决方法

也许你可以使用Variant数组?

array_map/array_filter/array_walk遍历数组的方式和foreach一样,谁要快一些啊?

array_map/array_filter/array_walk遍历数组的方式和foreach一样,谁要快一些啊?

array_walk相当于foreach:

$arr = [''Client''=&gt;''jQuery'',''Server''=&gt;''PHP''];
array_walk($arr, function($v, $k) {
    echo "键:$k 值:$v\n";
});
登录后复制
登录后复制

比如去除数组$arr元素的前后空白:

array_walk($arr, function(&amp;$v) { $v = trim($v); });
foreach($arr as &amp;$v) { $v = trim($v); }
array_filter: 用回调函数过滤数组中的单元,返回过滤后的数组

var_export(
    array_filter([1, 2, 3], function($v) {
        return $v &gt; 1;
    })
);
和
foreach([1, 2, 3] as $k =&gt; $v) {
    if($v &gt; 1) {
        $tmp[$k] = $v;
    }
}
var_export($tmp);
都输出:
array (
  1 =&gt; 2,
  2 =&gt; 3,
)
登录后复制
登录后复制

PHP数组映射化简(MapReduce):

array_map/array_reduce
array_map: 将回调函数作用到给定数组的单元上
var_export(
    array_map(function ($v) {
        return $v * $v;
    }, [1, 2, 3])
);
和
foreach([1, 2, 3] as $v) {
    $tmp[] = $v * $v;
}
var_export($tmp);
都输出:
array (
  0 =&gt; 1,
  1 =&gt; 4,
  2 =&gt; 9,
)
登录后复制
登录后复制

array_reduce: 用回调函数迭代地将数组简化(reduce)为单一的值
//输出16,即10+1+2+3,其中10作为初始值.

echo array_reduce([1, 2, 3], function($result, $item) {
    $result = $result + $item;
    return $result;
}, 10);
用foreach表达:
$result = 10;
foreach([1, 2, 3] as $v) {
    $result = $result + $v;
}
echo $result;
登录后复制
登录后复制

执行效果都一样,但是具体的用函数快还是用foreach快些啊

回复内容:

array_walk相当于foreach:

$arr = [''Client''=&gt;''jQuery'',''Server''=&gt;''PHP''];
array_walk($arr, function($v, $k) {
    echo "键:$k 值:$v\n";
});
登录后复制
登录后复制

比如去除数组$arr元素的前后空白:

array_walk($arr, function(&amp;$v) { $v = trim($v); });
foreach($arr as &amp;$v) { $v = trim($v); }
array_filter: 用回调函数过滤数组中的单元,返回过滤后的数组

var_export(
    array_filter([1, 2, 3], function($v) {
        return $v &gt; 1;
    })
);
和
foreach([1, 2, 3] as $k =&gt; $v) {
    if($v &gt; 1) {
        $tmp[$k] = $v;
    }
}
var_export($tmp);
都输出:
array (
  1 =&gt; 2,
  2 =&gt; 3,
)
登录后复制
登录后复制

PHP数组映射化简(MapReduce):

array_map/array_reduce
array_map: 将回调函数作用到给定数组的单元上
var_export(
    array_map(function ($v) {
        return $v * $v;
    }, [1, 2, 3])
);
和
foreach([1, 2, 3] as $v) {
    $tmp[] = $v * $v;
}
var_export($tmp);
都输出:
array (
  0 =&gt; 1,
  1 =&gt; 4,
  2 =&gt; 9,
)
登录后复制
登录后复制

array_reduce: 用回调函数迭代地将数组简化(reduce)为单一的值
//输出16,即10+1+2+3,其中10作为初始值.

echo array_reduce([1, 2, 3], function($result, $item) {
    $result = $result + $item;
    return $result;
}, 10);
用foreach表达:
$result = 10;
foreach([1, 2, 3] as $v) {
    $result = $result + $v;
}
echo $result;
登录后复制
登录后复制

执行效果都一样,但是具体的用函数快还是用foreach快些啊

关于delphi – 动态数组是否支持非零下限(对于VarArrayCreate兼容性)?delphi动态数组怎么赋值的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于arrays – Delphi – Byte数组到字符串、arrays – Delphi中字符串和记录的常量就地数组、arrays – Delphi:TVarRec与varArray的数组、array_map/array_filter/array_walk遍历数组的方式和foreach一样,谁要快一些啊?的相关知识,请在本站寻找。

本文标签: