Added various variants of splice() to facilitate array manipulations by
those who are accustomed to slinging backticks and slurping files with Perl. Someday perhaps we'll go whole-hog and implement more of the Perl-style splicing antics (allowing negative offset and/or length, and optionally passing a list of items to splice into the array.) git-svn-id: https://samskivert.googlecode.com/svn/trunk@827 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: ArrayUtil.java,v 1.14 2002/08/19 23:22:09 shaper Exp $
|
// $Id: ArrayUtil.java,v 1.15 2002/09/06 02:12:25 shaper Exp $
|
||||||
//
|
//
|
||||||
// samskivert library - useful routines for java programs
|
// samskivert library - useful routines for java programs
|
||||||
// Copyright (C) 2001 Walter Korman
|
// Copyright (C) 2001 Walter Korman
|
||||||
@@ -313,6 +313,214 @@ public class ArrayUtil
|
|||||||
return -(low + 1); // key not found.
|
return -(low + 1); // key not found.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new array sized to fit and populated with the
|
||||||
|
* subset of values from indexes <code>0</code> to </code>offset -
|
||||||
|
* 1</code> (inclusive) in the supplied array.
|
||||||
|
*
|
||||||
|
* @param values the array of values to splice.
|
||||||
|
* @param offset the index within the <code>values</code> array after
|
||||||
|
* which all subsequent values are to be removed. This must be a
|
||||||
|
* valid index within the <code>values</code> array.
|
||||||
|
*/
|
||||||
|
public static byte[] splice (byte[] values, int offset)
|
||||||
|
{
|
||||||
|
return splice(values, offset, values.length - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new array sized to fit and populated with the
|
||||||
|
* concatenated subset of values from indexes <code>0</code> to
|
||||||
|
* </code>offset - 1</code>, and <code>offset + length</code> to
|
||||||
|
* <code>values.length</code> (inclusive) in the supplied array.
|
||||||
|
*
|
||||||
|
* @param values the array of values to splice.
|
||||||
|
* @param offset the index within the <code>values</code> array at
|
||||||
|
* which the first element will be removed. This must be a valid
|
||||||
|
* index within the <code>values</code> array.
|
||||||
|
* @param length the number of elements to be removed. Note that
|
||||||
|
* <code>offset + length</code> must be a valid index within the
|
||||||
|
* <code>values</code> array.
|
||||||
|
*/
|
||||||
|
public static byte[] splice (byte[] values, int offset, int length)
|
||||||
|
{
|
||||||
|
// make sure we've something to work with
|
||||||
|
if (values == null) {
|
||||||
|
throw new IllegalArgumentException("Can't splice a null array.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// require that the entire range to remove be within the array bounds
|
||||||
|
int size = values.length;
|
||||||
|
int tstart = offset + length;
|
||||||
|
if (offset < 0 || tstart > size) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException(
|
||||||
|
"Splice range out of bounds [offset=" + offset +
|
||||||
|
", length=" + length + ", size=" + size + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new array and populate it with the spliced-in values
|
||||||
|
byte[] nvalues = new byte[size - length];
|
||||||
|
System.arraycopy(values, 0, nvalues, 0, offset);
|
||||||
|
System.arraycopy(values, tstart, nvalues, offset, size - tstart);
|
||||||
|
return nvalues;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new array sized to fit and populated with the
|
||||||
|
* subset of values from indexes <code>0</code> to </code>offset -
|
||||||
|
* 1</code> (inclusive) in the supplied array.
|
||||||
|
*
|
||||||
|
* @param values the array of values to splice.
|
||||||
|
* @param offset the index within the <code>values</code> array after
|
||||||
|
* which all subsequent values are to be removed. This must be a
|
||||||
|
* valid index within the <code>values</code> array.
|
||||||
|
*/
|
||||||
|
public static int[] splice (int[] values, int offset)
|
||||||
|
{
|
||||||
|
return splice(values, offset, values.length - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new array sized to fit and populated with the
|
||||||
|
* concatenated subset of values from indexes <code>0</code> to
|
||||||
|
* </code>offset - 1</code>, and <code>offset + length</code> to
|
||||||
|
* <code>values.length</code> (inclusive) in the supplied array.
|
||||||
|
*
|
||||||
|
* @param values the array of values to splice.
|
||||||
|
* @param offset the index within the <code>values</code> array at
|
||||||
|
* which the first element will be removed. This must be a valid
|
||||||
|
* index within the <code>values</code> array.
|
||||||
|
* @param length the number of elements to be removed. Note that
|
||||||
|
* <code>offset + length</code> must be a valid index within the
|
||||||
|
* <code>values</code> array.
|
||||||
|
*/
|
||||||
|
public static int[] splice (int[] values, int offset, int length)
|
||||||
|
{
|
||||||
|
// make sure we've something to work with
|
||||||
|
if (values == null) {
|
||||||
|
throw new IllegalArgumentException("Can't splice a null array.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// require that the entire range to remove be within the array bounds
|
||||||
|
int size = values.length;
|
||||||
|
int tstart = offset + length;
|
||||||
|
if (offset < 0 || tstart > size) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException(
|
||||||
|
"Splice range out of bounds [offset=" + offset +
|
||||||
|
", length=" + length + ", size=" + size + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new array and populate it with the spliced-in values
|
||||||
|
int[] nvalues = new int[size - length];
|
||||||
|
System.arraycopy(values, 0, nvalues, 0, offset);
|
||||||
|
System.arraycopy(values, tstart, nvalues, offset, size - tstart);
|
||||||
|
return nvalues;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new array sized to fit and populated with the
|
||||||
|
* subset of values from indexes <code>0</code> to </code>offset -
|
||||||
|
* 1</code> (inclusive) in the supplied array.
|
||||||
|
*
|
||||||
|
* @param values the array of values to splice.
|
||||||
|
* @param offset the index within the <code>values</code> array after
|
||||||
|
* which all subsequent values are to be removed. This must be a
|
||||||
|
* valid index within the <code>values</code> array.
|
||||||
|
*/
|
||||||
|
public static String[] splice (String[] values, int offset)
|
||||||
|
{
|
||||||
|
return splice(values, offset, values.length - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new array sized to fit and populated with the
|
||||||
|
* concatenated subset of values from indexes <code>0</code> to
|
||||||
|
* </code>offset - 1</code>, and <code>offset + length</code> to
|
||||||
|
* <code>values.length</code> (inclusive) in the supplied array.
|
||||||
|
*
|
||||||
|
* @param values the array of values to splice.
|
||||||
|
* @param offset the index within the <code>values</code> array at
|
||||||
|
* which the first element will be removed. This must be a valid
|
||||||
|
* index within the <code>values</code> array.
|
||||||
|
* @param length the number of elements to be removed. Note that
|
||||||
|
* <code>offset + length</code> must be a valid index within the
|
||||||
|
* <code>values</code> array.
|
||||||
|
*/
|
||||||
|
public static String[] splice (String[] values, int offset, int length)
|
||||||
|
{
|
||||||
|
// make sure we've something to work with
|
||||||
|
if (values == null) {
|
||||||
|
throw new IllegalArgumentException("Can't splice a null array.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// require that the entire range to remove be within the array bounds
|
||||||
|
int size = values.length;
|
||||||
|
int tstart = offset + length;
|
||||||
|
if (offset < 0 || tstart > size) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException(
|
||||||
|
"Splice range out of bounds [offset=" + offset +
|
||||||
|
", length=" + length + ", size=" + size + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new array and populate it with the spliced-in values
|
||||||
|
String[] nvalues = new String[size - length];
|
||||||
|
System.arraycopy(values, 0, nvalues, 0, offset);
|
||||||
|
System.arraycopy(values, tstart, nvalues, offset, size - tstart);
|
||||||
|
return nvalues;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new array sized to fit and populated with the
|
||||||
|
* subset of values from indexes <code>0</code> to </code>offset -
|
||||||
|
* 1</code> (inclusive) in the supplied array.
|
||||||
|
*
|
||||||
|
* @param values the array of values to splice.
|
||||||
|
* @param offset the index within the <code>values</code> array after
|
||||||
|
* which all subsequent values are to be removed. This must be a
|
||||||
|
* valid index within the <code>values</code> array.
|
||||||
|
*/
|
||||||
|
public static Object[] splice (Object[] values, int offset)
|
||||||
|
{
|
||||||
|
return splice(values, offset, values.length - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new array sized to fit and populated with the
|
||||||
|
* concatenated subset of values from indexes <code>0</code> to
|
||||||
|
* </code>offset - 1</code>, and <code>offset + length</code> to
|
||||||
|
* <code>values.length</code> (inclusive) in the supplied array.
|
||||||
|
*
|
||||||
|
* @param values the array of values to splice.
|
||||||
|
* @param offset the index within the <code>values</code> array at
|
||||||
|
* which the first element will be removed. This must be a valid
|
||||||
|
* index within the <code>values</code> array.
|
||||||
|
* @param length the number of elements to be removed. Note that
|
||||||
|
* <code>offset + length</code> must be a valid index within the
|
||||||
|
* <code>values</code> array.
|
||||||
|
*/
|
||||||
|
public static Object[] splice (Object[] values, int offset, int length)
|
||||||
|
{
|
||||||
|
// make sure we've something to work with
|
||||||
|
if (values == null) {
|
||||||
|
throw new IllegalArgumentException("Can't splice a null array.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// require that the entire range to remove be within the array bounds
|
||||||
|
int size = values.length;
|
||||||
|
int tstart = offset + length;
|
||||||
|
if (offset < 0 || tstart > size) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException(
|
||||||
|
"Splice range out of bounds [offset=" + offset +
|
||||||
|
", length=" + length + ", size=" + size + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new array and populate it with the spliced-in values
|
||||||
|
Object[] nvalues = new Object[size - length];
|
||||||
|
System.arraycopy(values, 0, nvalues, 0, offset);
|
||||||
|
System.arraycopy(values, tstart, nvalues, offset, size - tstart);
|
||||||
|
return nvalues;
|
||||||
|
}
|
||||||
|
|
||||||
/** The random object used when shuffling an array. */
|
/** The random object used when shuffling an array. */
|
||||||
protected static Random _rnd = new Random();
|
protected static Random _rnd = new Random();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
//
|
//
|
||||||
// $Id: ArrayUtilTest.java,v 1.1 2002/08/12 01:10:32 mdb Exp $
|
// $Id: ArrayUtilTest.java,v 1.2 2002/09/06 02:12:26 shaper Exp $
|
||||||
|
|
||||||
package com.samskivert.util;
|
package com.samskivert.util;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import com.samskivert.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the {@link ArrayUtil} class.
|
* Tests the {@link ArrayUtil} class.
|
||||||
*/
|
*/
|
||||||
@@ -21,73 +23,121 @@ public class ArrayUtilTest extends TestCase
|
|||||||
// test reversing an array
|
// test reversing an array
|
||||||
int[] values = new int[] { 0 };
|
int[] values = new int[] { 0 };
|
||||||
int[] work = (int[])values.clone();
|
int[] work = (int[])values.clone();
|
||||||
reverse(work);
|
ArrayUtil.reverse(work);
|
||||||
Log.info("reverse: " + StringUtil.toString(work));
|
Log.info("reverse: " + StringUtil.toString(work));
|
||||||
|
|
||||||
values = new int[] { 0, 1, 2 };
|
values = new int[] { 0, 1, 2 };
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
reverse(work);
|
ArrayUtil.reverse(work);
|
||||||
Log.info("reverse: " + StringUtil.toString(work));
|
Log.info("reverse: " + StringUtil.toString(work));
|
||||||
|
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
reverse(work, 0, 2);
|
ArrayUtil.reverse(work, 0, 2);
|
||||||
Log.info("reverse first-half: " + StringUtil.toString(work));
|
Log.info("reverse first-half: " + StringUtil.toString(work));
|
||||||
|
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
reverse(work, 1, 2);
|
ArrayUtil.reverse(work, 1, 2);
|
||||||
Log.info("reverse second-half: " + StringUtil.toString(work));
|
Log.info("reverse second-half: " + StringUtil.toString(work));
|
||||||
|
|
||||||
values = new int[] { 0, 1, 2, 3, 4 };
|
values = new int[] { 0, 1, 2, 3, 4 };
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
reverse(work, 1, 3);
|
ArrayUtil.reverse(work, 1, 3);
|
||||||
Log.info("reverse middle: " + StringUtil.toString(work));
|
Log.info("reverse middle: " + StringUtil.toString(work));
|
||||||
|
|
||||||
values = new int[] { 0, 1, 2, 3 };
|
values = new int[] { 0, 1, 2, 3 };
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
reverse(work);
|
ArrayUtil.reverse(work);
|
||||||
Log.info("reverse even: " + StringUtil.toString(work));
|
Log.info("reverse even: " + StringUtil.toString(work));
|
||||||
|
|
||||||
// test shuffling two elements
|
// test shuffling two elements
|
||||||
values = new int[] { 0, 1 };
|
values = new int[] { 0, 1 };
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
shuffle(work, 0, 1);
|
ArrayUtil.shuffle(work, 0, 1);
|
||||||
Log.info("first-half shuffle: " + StringUtil.toString(work));
|
Log.info("first-half shuffle: " + StringUtil.toString(work));
|
||||||
|
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
shuffle(work, 1, 1);
|
ArrayUtil.shuffle(work, 1, 1);
|
||||||
Log.info("second-half shuffle: " + StringUtil.toString(work));
|
Log.info("second-half shuffle: " + StringUtil.toString(work));
|
||||||
|
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
shuffle(work);
|
ArrayUtil.shuffle(work);
|
||||||
Log.info("full shuffle: " + StringUtil.toString(work));
|
Log.info("full shuffle: " + StringUtil.toString(work));
|
||||||
|
|
||||||
// test shuffling three elements
|
// test shuffling three elements
|
||||||
values = new int[] { 0, 1, 2 };
|
values = new int[] { 0, 1, 2 };
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
shuffle(work, 0, 2);
|
ArrayUtil.shuffle(work, 0, 2);
|
||||||
Log.info("first-half shuffle: " + StringUtil.toString(work));
|
Log.info("first-half shuffle: " + StringUtil.toString(work));
|
||||||
|
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
shuffle(work, 1, 2);
|
ArrayUtil.shuffle(work, 1, 2);
|
||||||
Log.info("second-half shuffle: " + StringUtil.toString(work));
|
Log.info("second-half shuffle: " + StringUtil.toString(work));
|
||||||
|
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
shuffle(work);
|
ArrayUtil.shuffle(work);
|
||||||
Log.info("full shuffle: " + StringUtil.toString(work));
|
Log.info("full shuffle: " + StringUtil.toString(work));
|
||||||
|
|
||||||
// test shuffling ten elements
|
// test shuffling ten elements
|
||||||
values = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
values = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
shuffle(work, 0, 5);
|
ArrayUtil.shuffle(work, 0, 5);
|
||||||
Log.info("first-half shuffle: " + StringUtil.toString(work));
|
Log.info("first-half shuffle: " + StringUtil.toString(work));
|
||||||
|
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
shuffle(work, 5, 5);
|
ArrayUtil.shuffle(work, 5, 5);
|
||||||
Log.info("second-half shuffle: " + StringUtil.toString(work));
|
Log.info("second-half shuffle: " + StringUtil.toString(work));
|
||||||
|
|
||||||
work = (int[])values.clone();
|
work = (int[])values.clone();
|
||||||
shuffle(work);
|
ArrayUtil.shuffle(work);
|
||||||
Log.info("full shuffle: " + StringUtil.toString(work));
|
Log.info("full shuffle: " + StringUtil.toString(work));
|
||||||
|
|
||||||
|
// test splicing with simple truncate beyond offset
|
||||||
|
values = new int[] { 0, 1, 2 };
|
||||||
|
work = (int[])values.clone();
|
||||||
|
work = ArrayUtil.splice(work, 0);
|
||||||
|
Log.info("splice truncate 0: " + StringUtil.toString(work));
|
||||||
|
|
||||||
|
work = (int[])values.clone();
|
||||||
|
work = ArrayUtil.splice(work, 1);
|
||||||
|
Log.info("splice truncate 1: " + StringUtil.toString(work));
|
||||||
|
|
||||||
|
work = (int[])values.clone();
|
||||||
|
work = ArrayUtil.splice(work, 2);
|
||||||
|
Log.info("splice truncate 2: " + StringUtil.toString(work));
|
||||||
|
|
||||||
|
values = new int[] { 0 };
|
||||||
|
work = (int[])values.clone();
|
||||||
|
work = ArrayUtil.splice(work, 0);
|
||||||
|
Log.info("single element splice truncate 0: " +
|
||||||
|
StringUtil.toString(work));
|
||||||
|
|
||||||
|
// test splicing out a single element
|
||||||
|
values = new int[] { 0, 1, 2 };
|
||||||
|
work = (int[])values.clone();
|
||||||
|
work = ArrayUtil.splice(work, 0, 1);
|
||||||
|
Log.info("splice concat 0, 1: " + StringUtil.toString(work));
|
||||||
|
|
||||||
|
work = (int[])values.clone();
|
||||||
|
work = ArrayUtil.splice(work, 1, 1);
|
||||||
|
Log.info("splice concat 1, 1: " + StringUtil.toString(work));
|
||||||
|
|
||||||
|
work = (int[])values.clone();
|
||||||
|
work = ArrayUtil.splice(work, 2, 1);
|
||||||
|
Log.info("splice concat 2, 1: " + StringUtil.toString(work));
|
||||||
|
|
||||||
|
// test splicing out two elements
|
||||||
|
values = new int[] { 0, 1, 2, 3 };
|
||||||
|
work = (int[])values.clone();
|
||||||
|
work = ArrayUtil.splice(work, 0, 2);
|
||||||
|
Log.info("splice concat 0, 2: " + StringUtil.toString(work));
|
||||||
|
|
||||||
|
work = (int[])values.clone();
|
||||||
|
work = ArrayUtil.splice(work, 1, 2);
|
||||||
|
Log.info("splice concat 1, 2: " + StringUtil.toString(work));
|
||||||
|
|
||||||
|
work = (int[])values.clone();
|
||||||
|
work = ArrayUtil.splice(work, 2, 2);
|
||||||
|
Log.info("splice concat 2, 2: " + StringUtil.toString(work));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Test suite ()
|
public static Test suite ()
|
||||||
|
|||||||
Reference in New Issue
Block a user