Thread overview
What is the replacement for deprecated array removal
Nov 18, 2019
kerdemdemir
Nov 18, 2019
kerdemdemir
Nov 18, 2019
kerdemdemir
Nov 18, 2019
kerdemdemir
Nov 18, 2019
kerdemdemir
Nov 18, 2019
mipri
November 18, 2019
I know my example can be shortened but please excuse me that I am pasting directly

import std.stdio;
import std.math;
import std.range;
import std.algorithm;
import std.typecons;

int[][4] tempMap;

void main()
{
    int[] temp  = [ 1, 2, 3 , 4 ,5 ];
    tempMap[0] =  temp.dup;
    tempMap[1] = temp.dup;
    tempMap[2] = temp.dup;
    tempMap[3] = temp.dup;

    int[] removeList;
    for ( int i = 0; i < tempMap.length; i++ )
    {
        if ( i%2)
            removeList ~=i;
    }
    tempMap[1].remove(removeList);
    writeln(tempMap);

}

Results with that warning:

onlineapp.d(24): Deprecation: function std.algorithm.mutation.remove!(cast(SwapStrategy)2, int[], int[]).remove is deprecated

How can I remove a list of indexes with remove ?

Erdem







November 18, 2019
    int[] removeList;
    for ( int i = 0; i < tempMap[0].length; i++ )
    {
        if ( i%2 == 0 )
            removeList ~=i;
    }
    writeln(removeList); (prints 0,2,4)
    tempMap[1].remove(0,2,4);
    tempMap[2].remove(removeList);
    tempMap[3].remove(tuple(0,1),tuple(2,3),tuple(4,5) );

Even weirder(at least for me)

int[] removeList is [0,2,4]

And .remove returns different results for .remove(0,2,4); and .remove(removeList)

Is there anyway to convert int[] to a sequence like 0,2,4

Erdem
November 18, 2019
On 11/18/19 3:01 PM, kerdemdemir wrote:
>      int[] removeList;
>      for ( int i = 0; i < tempMap[0].length; i++ )
>      {
>          if ( i%2 == 0 )
>              removeList ~=i;
>      }
>      writeln(removeList); (prints 0,2,4)
>      tempMap[1].remove(0,2,4);
>      tempMap[2].remove(removeList);
>      tempMap[3].remove(tuple(0,1),tuple(2,3),tuple(4,5) );
> 
> Even weirder(at least for me)
> 
> int[] removeList is [0,2,4]
> 
> And .remove returns different results for .remove(0,2,4); and ..remove(removeList)
> 
> Is there anyway to convert int[] to a sequence like 0,2,4
> 
> Erdem

If I follow the code correctly, it's treating your array as a tuple of pos/len to remove.

So it looks like your code is equivalent to

remove(tuple(0, 2));

Which is probably not what you want.

This probably explains why it's being deprecated, it's too confusing to the compiler.

And looking at git blame goes back to this PR: https://github.com/dlang/phobos/pull/6154

-Steve
November 18, 2019
On Monday, 18 November 2019 at 20:37:50 UTC, Steven Schveighoffer wrote:
> If I follow the code correctly, it's treating your array as a tuple of pos/len to remove.
>
> So it looks like your code is equivalent to
>
> remove(tuple(0, 2));
>
> Which is probably not what you want.
>
> This probably explains why it's being deprecated, it's too confusing to the compiler.
>
> And looking at git blame goes back to this PR: https://github.com/dlang/phobos/pull/6154
>
> -Steve

Sorry to be horrible at explaining but remove(tuple(0, 2)); is not what I want.

I have an array which goes from 0 to 5. And I want to remove odd numbers.

remove(tuple(0, 2)); defines a starting index and a ending index but I need to delete not consecutive elements. In the case of odd number from 0 to 5 that will be 1, 3 and 5 .

It is so weird when you type it is allowed like remove(1, 3, 5) but unexpectedly remove([1,3,5]) does not work the same way.

I think if I can convert [1,3,5] to a AliasSeq that could be ok also.

Erdem
November 18, 2019
On Monday, 18 November 2019 at 20:48:40 UTC, kerdemdemir wrote:
> On Monday, 18 November 2019 at 20:37:50 UTC, Steven Schveighoffer wrote:
>> If I follow the code correctly, it's treating your array as a tuple of pos/len to remove.
>>
>> So it looks like your code is equivalent to
>>
>> remove(tuple(0, 2));
>>
>> Which is probably not what you want.
>>
>> This probably explains why it's being deprecated, it's too confusing to the compiler.
>>
>> And looking at git blame goes back to this PR: https://github.com/dlang/phobos/pull/6154
>>
>> -Steve
>
> Sorry to be horrible at explaining but remove(tuple(0, 2)); is not what I want.
>
> I have an array which goes from 0 to 5. And I want to remove odd numbers.
>
> remove(tuple(0, 2)); defines a starting index and a ending index but I need to delete not consecutive elements. In the case of odd number from 0 to 5 that will be 1, 3 and 5 .
>
> It is so weird when you type it is allowed like remove(1, 3, 5) but unexpectedly remove([1,3,5]) does not work the same way.
>
> I think if I can convert [1,3,5] to a AliasSeq that could be ok also.
>
> Erdem

I read your message again now and I see that you weren't suggesting remove(tuple(0, 2)) but you were pointing out it is not what I want as well.

Is there any way to remove list of elements efficiently with a dynamical array?

Or is there anyway converting a dynamical array into a form which is like a AliasSeq?


Erdem

November 18, 2019
On 11/18/19 3:53 PM, kerdemdemir wrote:

> Is there any way to remove list of elements efficiently with a dynamical array?

It seems kind of silly that it's not allowed, but maybe it will be possible after the deprecation is removed.

But you could do something like this:

list = list.remove!(a => removeList.canFind(a));

This is going to suck. Because it's O(n^2). Should be O(n + m) way to do it (assuming you have a sorted index list).

> 
> Or is there anyway converting a dynamical array into a form which is like a AliasSeq?

An AliasSeq is a compile-time construct, and cannot be created from a runtime array.

-Steve
November 18, 2019
On Monday, 18 November 2019 at 21:14:53 UTC, Steven Schveighoffer wrote:
> On 11/18/19 3:53 PM, kerdemdemir wrote:
>
>> Is there any way to remove list of elements efficiently with a dynamical array?
>
> It seems kind of silly that it's not allowed, but maybe it will be possible after the deprecation is removed.
>
> But you could do something like this:
>
> list = list.remove!(a => removeList.canFind(a));
>
> This is going to suck. Because it's O(n^2). Should be O(n + m) way to do it (assuming you have a sorted index list).
>
>> 
>> Or is there anyway converting a dynamical array into a form which is like a AliasSeq?
>
> An AliasSeq is a compile-time construct, and cannot be created from a runtime array.
>
> -Steve

Thanks for awesome answers man ,

Yes that sucks real hard because unlike that dummy example in my real case == compression will be too expensive I can't simply use canFind on every index.

I guess I need to recreate a new dynamical array each time which is also horrible.

It is a bit weird that such a general case like removing list of elements does not work.

And I really do not know the real use of [0,1,2,3].remove(1,2,3). I mean in unit test it looks cool but in real life you will have dynamically calculated indexes.

Erdem






November 18, 2019
On Monday, 18 November 2019 at 21:25:12 UTC, kerdemdemir wrote:
> It is a bit weird that such a general case like removing list of elements does not work.
>
> And I really do not know the real use of [0,1,2,3].remove(1,2,3). I mean in unit test it looks cool but in real life you will have dynamically calculated indexes.
>
> Erdem

It seems like a defect in phobos to me as well. Fortunately phobos
is written in D so you can just copy&paste this into your code:
https://github.com/dlang/phobos/blob/master/std/algorithm/mutation.d#L2160

however, it still doesn't return the same thing as x.remove(1,2,3).

... maybe it'd be simpler to drop down to C-style D?

// no checks for out-of-bounds or unsorted offsets
void myRemove(ref int[] array, int[] offsets) {
    int from, to, offset;

    while (from < array.length) {
        if (offset < offsets.length && from == offsets[offset]) {
            ++offset;
            ++from;
        } else if (from == to) {
            ++to;
            ++from;
        } else {
            array[to++] = array[from++];
        }
    }
    array.length = to;
}

unittest {
    int[] x = [1, 2, 3];
    int[] y = x.dup, z = x.dup, q = x.dup;
    myRemove(x, [0]);
    myRemove(y, []);
    myRemove(z, [2]);
    myRemove(q, [1, 2]);
    assert(x == [2, 3]);
    assert(y == [1, 2, 3]);
    assert(z == [1, 2]);
    assert(q == [1]);
}

Perhaps it's nice to have the option?