Thread overview
remove element from dyn array by element, (not by index)
Jan 15, 2008
Bjoern
Jan 15, 2008
bearophile
Jan 15, 2008
Bjoern
January 15, 2008
Hi,
unlike the examples I found on D.learn regarding this topic I want to remove an element from an dynamic array without knowing the index.

A few questions :

//Remove element try #1
T[] remove(T,E)(T[] arr, E element)
{
  for(uint i = 0;i < arr.length-1;i++)
  {
    if (arr[i] == element)
      return i==arr.length-1 ? arr[0..$-1].dup : arr[0..i] ~ arr[i+1 .. $];		
  }
  // return T[]    ???????????????????
}

or is it preferable to use :
//Remove element try #2
void remove(T,E)(inout T[] arr, in E element)
{}

Given :
class myclass
{
  this(int x){}
}

myclass[] objarr;

auto a = new myclass(1);
objarr ~= a;
auto b = new myclass(2);
objarr ~= b;
auto c = new myclass(3);
objarr ~= c;

objarr.remove(b);

Do I need opEquals within myclass ?

Let's assume that the passed parameter is f.i. a priority index. In case  that I want to sort objarr ordered by this /priority index/, is toHash() the override of choice ?

Can you please help me to improve the code ?
Many thanks in advance, Bjoern
January 15, 2008
This may help clear your mind some:

import std.stdio: writefln;
import std.string: format;

void removeBang(T)(ref T[] arr, T el) {
    foreach(i, x; arr)
        if (x == el) {
            arr = arr[0 .. i] ~ arr[i+1 .. $];
            break;
        }
}

class C(bool withEqual) {
    int x;
    this(int x) {
        this.x = x;
    }
    string toString() {
        return format("C(%d)", x);
    }
    static if (withEqual) {
        bool opEquals(C other) {
            return this.x == other.x;
        }
    }
}

void main() {
    int[] a = [1, 2, 3, 4, 1];
    writefln(a);
    a.removeBang(4);
    writefln(a);
    writefln;

    alias C!(true) C1;
    auto b = new C1(2);
    C1[] oa = [new C1(1), b, new C1(3)];
    removeBang(oa, b);
    writefln(oa);
    removeBang(oa, new C1(1));
    writefln(oa);
    writefln;

    alias C!(false) C2;
    auto b2 = new C2(2);
    C2[] oa2 = [new C2(1), b2, new C2(3)];
    removeBang(oa2, b2);
    writefln(oa2);
    removeBang(oa2, new C2(1));
    writefln(oa2);
}


Output:

[1,2,3,4,1]
[1,2,3,1]

[C(1),C(3)]
[C(3)]

[C(1),C(3)]
[C(1),C(3)]

Bye,
bearophile
January 15, 2008
Thanks,
much more than I've expected from an answere!
and beside,thanks to your answere I know that I've to learn,learn,... :)
Bjoern