How to Delete Multiple Values from a Vector

How to delete multiple values from a vector?

The %in% operator tells you which elements are among the numers to remove:

> a <- sample (1 : 10)
> remove <- c (2, 3, 5)
> a
[1] 10 5 2 7 1 6 3 4 8 9
> a %in% remove
[1] FALSE TRUE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
> a [! a %in% remove]
[1] 10 7 1 6 4 8 9

Note that this will silently remove incomparables (stuff like NA or Inf) as well (while it will keep duplicate values in a as long as they are not listed in remove).

  • If a can contain incomparables, but remove will not, we can use match, telling it to return 0 for non-matches and incomparables (%in% is a conventient shortcut for match):

    > a <- c (a, NA, Inf)
    > a
    [1] 10 5 2 7 1 6 3 4 8 9 NA Inf
    > match (a, remove, nomatch = 0L, incomparables = 0L)
    [1] 0 3 1 0 0 0 2 0 0 0 0 0
    > a [match (a, remove, nomatch = 0L, incomparables = 0L) == 0L]
    [1] 10 7 1 6 4 8 9 NA Inf

    incomparables = 0 is not needed as incomparables will anyways not match, but I'd include it for the sake of readability.

    This is, btw., what setdiff does internally (but without the unique to throw away duplicates in a which are not in remove).

  • If remove contains incomparables, you'll have to check for them individually, e.g.

    if (any (is.na (remove))) 
    a <- a [! is.na (a)]

    (This does not distinguish NA from NaN but the R manual anyways warns that one should not rely on having a difference between them)

    For Inf/ -Inf you'll have to check both sign and is.finite

How to delete multiple values from a vector? But not all of them

You can get it very simply with pmatch:

set[-pmatch(played,set)]
# [1] 1 1 3 4 8 8 10

And here's another idea:

rep.int(seq_len(max(set)),tabulate(set)-tabulate(played,nbins=max(set)))
# [1] 1 1 3 4 8 8 10

Erasing multiple objects from a std::vector?

I am offering several methods:

1. A fast method that does not retain the original order of the elements:

Assign the current last element of the vector to the element to erase, then erase the last element. This will avoid big moves and all indexes except the last will remain constant. If you start erasing from the back, all precomputed indexes will be correct.

void quickDelete( int idx )
{
vec[idx] = vec.back();
vec.pop_back();
}

I see this essentially is a hand-coded version of the erase-remove idiom pointed out by Klaim ...

2. A slower method that retains the original order of the elements:

Step 1: Mark all vector elements to be deleted, i.e. with a special value. This has O(|indexes to delete|).

Step 2: Erase all marked elements using v.erase( remove (v.begin(), v.end(), special_value), v.end() );. This has O(|vector v|).

The total run time is thus O(|vector v|), assuming the index list is shorter than the vector.

3. Another slower method that retains the original order of the elements:

Use a predicate and remove if as described in https://stackoverflow.com/a/3487742/280314 . To make this efficient and respecting the requirement of
not "sorting then linearly erasing with an offset", my idea is to implement the predicate using a hash table and adjust the indexes stored in the hash table as the deletion proceeds on returning true, as Klaim suggested.

How to remove multiple elements in Vector in Java?

To remove multiple values

    Vector vector = new Vector();
vector.add("value1");
vector.add("value2");
vector.add("value3");
vector.add("value4");
System.out.println("Size : "+vector.size());
// to remove single value
vector.remove("value1");
System.out.println("Size : "+vector.size());
Vector itemsToRemove = new Vector();
itemsToRemove.add("value3");
itemsToRemove.add("value4");
//remove multiple values
vector.removeAll(itemsToRemove);
System.out.println("Size : "+vector.size());

//to remove all elements
vector.removeAllElements();
// or
vector.clear();

But instead of using Vector consider to use ArrayList since Vector is obsolete collection.
Read this : Why is Java Vector class considered obsolete or deprecated?

Also use generics Like ArrayList<String> idList = new ArrayList() if you store only String elements in list.

If you want to skip duplicates when adding elements in Vector, use the following code

   Vector vector = new Vector() {
@Override
public synchronized boolean add(Object e) {
if(!contains(e)){
return super.add(e);
}
System.out.println("Element " + e +" is duplicate");
return false ;
}
};

But if you want to add only unique elements, use Set

Remove values from a vector based on a condition

this solve your problem:

x <- x[abs(x) <= 8]

Most efficient way of erasing/deleting multiple std::vector elements while retaining original order?

In <algorithm> there is a remove_if function which squeezes all values not removed to the front maintaining the order. This works if those 200 elements can be purely determined by the values, not index.

This is essentially the Erase-remove idiom you have linked to. remove_if is guaranteed to perform O(N) comparisons (and at most O(N) copyings), which would be more efficient than sorting (O(N log N)), although your last option doesn't actually require sorting if the indices are determined from values (just scan in the reversed direction while copying).

Nevertheless, using remove_if (if you can) is better than the other 2 options because the implementation has already been written for you, so there's less chance of logical error and conveys better what (not how) to do.

remove certain values from a vector

We can do a setdiff if the elements are unique by looping over the list elements with lapply

lapply(a,  setdiff, rm)

Or else, use %in% and then negate

lapply(a, function(x) x[!x %in% rm])


Related Topics



Leave a reply



Submit