www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What is the replacement for deprecated array removal

reply kerdemdemir <kerdemdemir gmail.com> writes:
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
Nov 18 2019
parent reply kerdemdemir <kerdemdemir gmail.com> writes:
     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
Nov 18 2019
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Nov 18 2019
parent reply kerdemdemir <kerdemdemir gmail.com> writes:
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
Nov 18 2019
parent reply kerdemdemir <kerdemdemir gmail.com> writes:
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
Nov 18 2019
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Nov 18 2019
parent reply kerdemdemir <kerdemdemir gmail.com> writes:
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
Nov 18 2019
parent mipri <mipri minimaltype.com> writes:
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?
Nov 18 2019