Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java eqivalent method of "splice(a,b,...)" in JavaScript method

someArray.splice(a,b,...) method in JavaScript adds or removes items to/from array. What could be good and simple solution to implement such method in Java language? Assume we have String[] array.

like image 430
Ernestas Gruodis Avatar asked Feb 11 '23 16:02

Ernestas Gruodis


1 Answers

Here is a Java implementation of the Array.prototype.splice() method as per the JavaScript MDN specification.

  public static <T>T[] splice(final T[] array, int start) {
    if (start < 0)
      start += array.length;

    return splice(array, start, array.length - start);
  }

  @SuppressWarnings("unchecked")
  public static <T>T[] splice(final T[] array, int start, final int deleteCount) {
    if (start < 0)
      start += array.length;

    final T[] spliced = (T[])Array.newInstance(array.getClass().getComponentType(), array.length - deleteCount);
    if (start != 0)
      System.arraycopy(array, 0, spliced, 0, start);

    if (start + deleteCount != array.length)
      System.arraycopy(array, start + deleteCount, spliced, start, array.length - start - deleteCount);

    return spliced;
  }

  @SuppressWarnings("unchecked")
  public static <T>T[] splice(final T[] array, int start, final int deleteCount, final T ... items) {
    if (start < 0)
      start += array.length;

    final T[] spliced = (T[])Array.newInstance(array.getClass().getComponentType(), array.length - deleteCount + items.length);
    if (start != 0)
      System.arraycopy(array, 0, spliced, 0, start);

    if (items.length > 0)
      System.arraycopy(items, 0, spliced, start, items.length);

    if (start + deleteCount != array.length)
      System.arraycopy(array, start + deleteCount, spliced, start + items.length, array.length - start - deleteCount);

    return spliced;
  }

The following JUnit code tests this implementation:

@Test
  public void testSplice() {
    final String[] array = new String[] {"a", "b", "c", "d", "e", "f"};

    Assert.assertArrayEquals(new String[] {"c", "d", "e", "f"}, Arrays.splice(array, 0, 2));
    Assert.assertArrayEquals(new String[] {"a", "d", "e", "f"}, Arrays.splice(array, 1, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "e", "f"}, Arrays.splice(array, 2, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "f"}, Arrays.splice(array, 3, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d"}, Arrays.splice(array, 4, 2));
    try {
      Arrays.splice(array, 5, 2);
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }

    try {
      Arrays.splice(array, -2, 3);
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d"}, Arrays.splice(array, -2, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "f"}, Arrays.splice(array, -3, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "e", "f"}, Arrays.splice(array, -4, 2));
    Assert.assertArrayEquals(new String[] {"a", "d", "e", "f"}, Arrays.splice(array, -5, 2));
    Assert.assertArrayEquals(new String[] {"c", "d", "e", "f"}, Arrays.splice(array, -6, 2));
    try {
      Arrays.splice(array, -7, 2);
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }

    Assert.assertArrayEquals(new String[] {}, Arrays.splice(array, 0));
    Assert.assertArrayEquals(new String[] {"a"}, Arrays.splice(array, 1));
    Assert.assertArrayEquals(new String[] {"a", "b"}, Arrays.splice(array, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "c"}, Arrays.splice(array, 3));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d"}, Arrays.splice(array, 4));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d", "e"}, Arrays.splice(array, 5));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d", "e", "f"}, Arrays.splice(array, 6));
    try {
      Arrays.splice(array, 7);
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }

    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d", "e"}, Arrays.splice(array, -1));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d"}, Arrays.splice(array, -2));
    Assert.assertArrayEquals(new String[] {"a", "b", "c"}, Arrays.splice(array, -3));
    Assert.assertArrayEquals(new String[] {"a", "b"}, Arrays.splice(array, -4));
    Assert.assertArrayEquals(new String[] {"a"}, Arrays.splice(array, -5));
    Assert.assertArrayEquals(new String[] {}, Arrays.splice(array, -6));
    try {
      Arrays.splice(array, -7);
      Assert.fail("Expected NegativeArraySizeException");
    }
    catch (final NegativeArraySizeException e) {
    }

    Assert.assertArrayEquals(new String[] {"x", "y", "z", "c", "d", "e", "f"}, Arrays.splice(array, 0, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "x", "y", "z", "d", "e", "f"}, Arrays.splice(array, 1, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "b", "x", "y", "z", "e", "f"}, Arrays.splice(array, 2, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "x", "y", "z", "f"}, Arrays.splice(array, 3, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d", "x", "y", "z"}, Arrays.splice(array, 4, 2, "x", "y", "z"));
    try {
      Arrays.splice(array, 5, 2, "x", "y", "z");
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }

    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d", "x", "y", "z"}, Arrays.splice(array, -2, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "x", "y", "z", "f"}, Arrays.splice(array, -3, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "b", "x", "y", "z", "e", "f"}, Arrays.splice(array, -4, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "x", "y", "z", "d", "e", "f"}, Arrays.splice(array, -5, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"x", "y", "z", "c", "d", "e", "f"}, Arrays.splice(array, -6, 2, "x", "y", "z"));
    try {
      Arrays.splice(array, -7, 2, "x", "y", "z");
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }
  }

Edit: As @denys-séguret pointed out correctly, this implementation differs from the JavaScript spec as it does not mutate/modify the original array. Instead, this implementation returns a new array instance.

Edit: This implementation is available with the following maven artifact, at the given maven repo:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>org.safris.commons</groupId>
      <artifactId>commons-lang</artifactId>
      <version>1.6.4</version>
    </dependency>
  </dependencies>
  ...
  <repositories>
    <repository>
      <id>mvn.repo.safris.org</id>
      <url>http://mvn.repo.safris.org/m2</url>
    </repository>
  </repositories>
  ...
</project>
like image 69
Seva Safris Avatar answered Feb 13 '23 06:02

Seva Safris