如何删除空元素或元素与数组指针为零? 一个通用的解决方案将受到欢迎。
Answer 1:
你可以写这样的:
type
TArrayHelper = class
class function RemoveAll<T>(var Values: TArray<T>; const Value: T); static;
end;
....
function TArrayHelper.RemoveAll<T>(var Values: TArray<T>; const Value: T);
var
Index, Count: Integer;
DefaultComparer: IEqualityComparer<T>;
begin
// obtain an equality comparer for our type T
DefaultComparer := TEqualityComparer<T>.Default;
// loop over the the array, only retaining non-matching values
Count := 0;
for Index := 0 to high(Values) do begin
if not DefaultComparer.Equals(Values[Index], Value) then begin
Values[Count] := Values[Index];
inc(Count);
end;
end;
// re-size the array
SetLength(Values, Count);
end;
假设你有一个指针数组:
var
arr: TArray<Pointer>;
然后,你将消除nil
元素是这样的:
TArrayHelper.RemoveAll<Pointer>(arr, nil);
这段代码使用了简单的方法,并始终使用默认的比较。 对于更复杂的类型也是白搭。 例如,有些记录需要定制comparers。 您将需要提供一个比较器来支持。
以上实现尽可能简单。 在性能方面,它很可能是在没有匹配值,或者很少,被发现可能常见的场景浪费。 这是因为该版本以上无条件地分配,即使这两个指标都是一样的。
相反,如果有与性能问题,则可能通过数组步进至于第一场比赛优化代码。 然后才开始移动值。
function TArrayHelper.RemoveAll<T>(var Values: TArray<T>; const Value: T);
var
Index, Count: Integer;
DefaultComparer: IEqualityComparer<T>;
begin
// obtain an equality comparer for our type T
DefaultComparer := TEqualityComparer<T>.Default;
// step through the array until we find a match, or reach the end
Count := 0;
while (Count<=high(Values))
and not DefaultComparer.Equals(Values[Count], Value) do begin
inc(Count);
end;
// Count is either the index of the first match or one off the end
// loop over the rest of the array copying non-matching values to the next slot
for Index := Count to high(Values) do begin
if not DefaultComparer.Equals(Values[Index], Value) then begin
Values[Count] := Values[Index];
inc(Count);
end;
end;
// re-size the array
SetLength(Values, Count);
end;
正如你可以看到这是一个很大的困难进行分析。 你只考虑这样做,如果原来的版本是一个瓶颈。
文章来源: How to remove empty/nil elements from Array?