/*
This file is part of the software framework JStatCom,
a library for building applications for data based analysis.
Copyright (C) 2000-2005 Markus Kraetzig
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
*/
package com.jstatcom.util;
import java.util.ArrayList;
/**
* A collection of static methods that are related to arrays of strings.
*
* All methods implemented do not modify the original input. Results are always
* newly created arrays. If the input is somehow wrong an appropriate exception
* is thrown. All methods require that the input arrays have the same number of
* elements in each row.
*
* @author Markus Kraetzig
*/
public final class UStringArray {
/**
* Not to be invoked.
*/
private UStringArray() {
}
/**
* Appends toAppend to the columns of orig and
* returns the new merged array. This only works, if orig and
* toAppend have the same number of rows.
*
* @param orig
* the array to append the columns of toAppend to
* @param toAppend
* the arrays to be appended to orig
* @return a new array orig~toAppend
* @throws IllegalArgumentException
* if (orig.length != toAppend.length) or
* if (orig == null || toAppend == null) or if
* rows of an argument have different lengths
*/
public static String[][] appendStringCols(String[][] orig,
String[][] toAppend) {
if (orig == null || toAppend == null)
throw new IllegalArgumentException("Argument was null.");
checkRowLengths(orig);
checkRowLengths(toAppend);
if (orig.length != toAppend.length)
throw new IllegalArgumentException(
"Different number of rows (orig:" + orig.length
+ ", toAppend:" + toAppend.length + ").");
int origCols = orig[0].length;
int toAppendCols = toAppend[0].length;
String[][] newMat = new String[orig.length][origCols + toAppendCols];
for (int i = 0; i < newMat.length; i++) {
System.arraycopy(orig[i], 0, newMat[i], 0, origCols);
System.arraycopy(toAppend[i], 0, newMat[i], origCols, toAppendCols);
}
return newMat;
}
/**
* Appends toAppend to the rows of orig and
* returns the new merged array. This only works, if orig and
* toAppend have the same number of columns.
*
* @param orig
* the array to append the rows of toAppend to
* @param toAppend
* the arrays to be appended to orig
* @return a new array orig|toAppend
* @throws IllegalArgumentException
* if (orig[0].length != toAppend[0].length) or
* if (orig == null || toAppend == null) or if
* rows of an argument have different lengths
*/
public static String[][] appendStringRows(String[][] orig,
String[][] toAppend) {
if (orig == null || toAppend == null)
throw new IllegalArgumentException("Argument was null.");
checkRowLengths(orig);
checkRowLengths(toAppend);
if (orig.length == 0)
return cloneStringArray(toAppend);
if (toAppend.length == 0)
return cloneStringArray(orig);
if (orig[0].length != toAppend[0].length)
throw new IllegalArgumentException(
"Different number of columns for appendStringRows (orig:"
+ orig[0].length + ", toAppend:"
+ toAppend[0].length + ").");
int origRows = orig.length;
int toAppendRows = toAppend.length;
String[][] newMat = new String[origRows + toAppendRows][];
for (int i = 0; i < origRows; i++)
newMat[i] = orig[i].clone();
for (int i = 0; i < toAppendRows; i++)
newMat[origRows + i] = toAppend[i].clone();
return newMat;
}
/**
* Appends suffix to the elements of orig and
* returns the new string array.
*
* @param orig
* the original string array
* @param suffix
* the suffix to be appended to all elements of orig
* @return a new string array
*
* @throws IllegalArgumentException
* if (orig == null || suffix == null) or if rows
* of argument have different lengths
*/
public static String[][] appendSuffix(String[][] orig, String suffix) {
if (orig == null || suffix == null)
throw new IllegalArgumentException("Argument was null.");
checkRowLengths(orig);
String[][] newMat = cloneStringArray(orig);
for (int i = 0; i < newMat.length; i++)
for (int j = 0; j < newMat[0].length; j++)
newMat[i][j] = newMat[i][j] + suffix;
return newMat;
}
/**
* Appends suffix to the elements of orig and
* returns the new string array.
*
* @param orig
* the original string array
* @param suffix
* the suffix to be appended to all elements of orig
* @return a new string array
*
* @throws IllegalArgumentException
* if (orig == null || suffix == null)
*/
public static String[] appendSuffix(String[] orig, String suffix) {
if (orig == null || suffix == null)
throw new IllegalArgumentException("Argument was null.");
String[][] newMat = appendSuffix(toStringMatrix(orig), suffix);
return getStringCol(newMat, 0);
}
/**
* Checks whether all rows of arg have the same number of
* columns. If the check fails, an exception is thrown.
*
* @param arg
* the String[][] to check
* @throws IllegalArgumentException
* if the rows of arg have different lengths
*/
public static void checkRowLengths(String[][] arg) {
if (arg != null && arg.length > 0) {
int n = arg[0].length;
for (int i = 0; i < arg.length; i++)
if (arg[i].length != n)
throw new IllegalArgumentException(
"Rows have different lengths.");
}
}
/**
* Gets an identical copy of x.
*
* @return the cloned array or
*
* null if (x == null)
* -
*
new String[0][0] if (x.length == 0 || x[0].length == 0)
*
* @throws IllegalArgumentException
* if rows of argument have different lengths
*/
public static String[][] cloneStringArray(String[][] x) {
if (x == null)
return null;
checkRowLengths(x);
if (x.length == 0 || x[0].length == 0)
return new String[0][0];
String[][] y = x.clone();
for (int i = 0; i < x.length; i++)
y[i] = x[i].clone();
return y;
}
/**
* Compares two string arrays and returns true. if the
* dimensions are the same and all elements are equal. If two elements of
* arg1 and arg2 are null,
* they are considered to be equal. The comparison is case sensitive.
*
* @param arg1
* string array to compare
* @param arg2
* string array to compare
* @return true if dimensions and all elements are equal or
* if arg1, arg2 have both at least one dimension of
* zero,
* false otherwise
* @throws IllegalArgumentException
* if rows of an argument have different lengths
*/
public static boolean compareStringArrays(String[][] arg1, String[][] arg2) {
if (arg1 == null || arg2 == null)
return false;
checkRowLengths(arg1);
checkRowLengths(arg2);
// Tests whether at least one dimension is 0 in both arguments.
if ((arg1.length == 0 || arg1[0].length == 0)
&& (arg2.length == 0 || arg2[0].length == 0))
return true;
if (arg1.length != arg2.length || arg1[0].length != arg2[0].length)
return false;
for (int i = 0; i < arg1.length; i++)
for (int j = 0; j < arg1[0].length; j++) {
if (!(arg1[i][j] == null && arg2[i][j] == null)) // equal if
// both are
// null
if (arg1[i][j] != null && !arg1[i][j].equals(arg2[i][j]))
return false;
}
return true;
}
/**
* Creates an index with its elements starting with name
* followed by the integer part of the respective element of
* idx. The resulting string array has length
* idx.length.
*
* @param name
* the string with the prefix for the index
* @param idx
* the array containing the indices to be appended to
* name
* @return a idx.length string array
* @throws IllegalArgumentException
* if (name == null || idx == null)
*/
public static String[] createNamedIndex(String name, double[] idx) {
if (name == null || idx == null)
throw new IllegalArgumentException("Argument was null.");
String[] s = new String[idx.length];
for (int i = 0; i < s.length; i++)
s[i] = name + (int) idx[i];
return s;
}
/**
* Deletes the column colIndex from arg.
*
* @param arg
* the string array to delete the column from
* @param colIndex
* index of the column
* @return new string array with the deleted column
* @throws IllegalArgumentException
* if (arg == null) or
* if (colIndex < 0 || arg[0].length < colIndex)
* or if (arg.length == 0 || arg[0].length == 0)
* or if rows of argument have different lengths
*/
public static String[][] delCol(String[][] arg, int colIndex) {
if (arg == null)
throw new IllegalArgumentException("Argument was null.");
if (arg.length == 0 || arg[0].length == 0)
throw new IllegalArgumentException("Argument was empty.");
checkRowLengths(arg);
if (colIndex < 0 || arg[0].length <= colIndex)
throw new IllegalArgumentException("Bad column index: " + colIndex
+ ".");
if (arg[0].length - 1 == 0)
return new String[0][0];
String[][] newArray = new String[arg.length][arg[0].length - 1];
for (int i = 0; i < arg.length; i++)
for (int j = 0, k = 0; j < arg[0].length; j++) {
if (j != colIndex)
newArray[i][k++] = arg[i][j];
}
return newArray;
}
/**
* Deletes columns of arg that have been selected by
* index and returns a new array with the remaining columns.
* A column is selected for deletion if the corresponding index entry is
* nonzero.
*
* @param arg
* the array to delete columns from
* @param index
* the arg[0].length x 1 int array
*
* @return a new array with the selected columns deleted or
* new String[0][0] if all columns where selected for
* deletion or if arg.length == 0
*
* @throws IllegalArgumentException
* if (arg == null || index == null) or
* if (arg[0].length != index.length) or
* if ((arg.length == 0 || arg[0].length == 0) && index.length > 0)
* or if rows of argument have different lengths
*/
public static String[][] delif(String[][] arg, int[] index) {
if (arg == null || index == null)
throw new IllegalArgumentException("Argument was null.");
if (index.length == 0 && (arg.length == 0 || arg[0].length == 0))
return new String[0][0];
if (arg.length == 0 || arg[0].length == 0)
throw new IllegalArgumentException("Argument was empty.");
checkRowLengths(arg);
return selif(arg, UMatrix.flipIndex(index));
}
/**
* Deletes the row rowIndex from arg.
*
* @param arg
* the string array to delete the row from
* @param rowIndex
* index of the row
* @return new string array with the deleted row
* @throws IllegalArgumentException
* if (arg == null) or
* if (rowIndex < 0 || arg.length < rowIndex)
* or if (arg.length == 0 || arg[0].length == 0)
* or if rows of argument have different lengths
*/
public static String[][] delRow(String[][] arg, int rowIndex) {
if (arg == null)
throw new IllegalArgumentException("Argument was null.");
if (arg.length == 0 || arg[0].length == 0)
throw new IllegalArgumentException("Argument was empty.");
checkRowLengths(arg);
if (rowIndex < 0 || arg.length <= rowIndex)
throw new IllegalArgumentException("Bad row index: " + rowIndex
+ ".");
String[][] newSA = new String[arg.length - 1][];
for (int i = 0, j = 0; i < arg.length; i++)
if (rowIndex != i)
newSA[j++] = arg[i].clone();
return newSA;
}
/**
* Deletes rows of arg that have been selected by
* index and returns a new array with the remaining rows. A
* row is selected for deletion if the corresponding index entry is nonzero.
*
* @param arg
* the array to delete rows from
* @param index
* the arg[0].length x 1 int array
*
* @return a new array with the selected rows deleted or
* new String[0][0] if all rows where selected for
* deletion or if arg.length == 0
*
* @throws IllegalArgumentException
* if (arg == null || index == null) or
* if (arg.length != index.length) or
* if ((arg.length == 0 || arg[0].length == 0) && index.length > 0)
* or if rows of arg have different lengths
*/
public static String[][] delRowsIf(String[][] arg, int[] index) {
if (arg == null || index == null)
throw new IllegalArgumentException("Argument was null.");
if (index.length == 0 && (arg.length == 0 || arg[0].length == 0))
return new String[0][0];
if (arg.length == 0 || arg[0].length == 0)
throw new IllegalArgumentException("Argument was empty.");
checkRowLengths(arg);
return selRowsIf(arg, UMatrix.flipIndex(index));
}
/**
* Deletes rows of arg that have been selected by
* index and returns a new array with the remaining rows. A
* row is selected for deletion if the corresponding index entry is set to 1
* (or != 0).
*
* @param arg
* the array to delete rows from
* @param rowIndex
* the arg.length x 1 int array with 1's and 0's
* (all values different from 0 select a row, but usually 1)
*
* @return a new array with the selected rows deleted or
* new String[0][0] if all rows where selected for
* deletion or if arg.length == 0
*
* @throws IllegalArgumentException
* if (arg == null || index == null) or
* if (arg.length != index.length)
*/
public static String[] delRowsIf(String[] arg, int[] rowIndex) {
if (arg == null || rowIndex == null)
throw new IllegalArgumentException("Argument was null.");
return selRowsIf(arg, UMatrix.flipIndex(rowIndex));
}
/**
* Gets the column of the array arg specified with
* colIndex. The index starts with 0 as usual.
*
* @param arg
* the array to extract a column from
* @param colIndex
* the index of the column to extract (starting from 0)
* @return a one dimensional string array with the column data
* @throws IllegalArgumentException
* if (arg == null) or
* if (arg.length == 0) or if the index is
* outside the valid array bounds or if rows of argument have
* different lengths
*/
public static String[] getStringCol(String[][] arg, int colIndex) {
if (arg == null)
throw new IllegalArgumentException("Argument was null.");
checkRowLengths(arg);
if (arg.length == 0)
throw new IllegalArgumentException("Argument has zero rows.");
if (colIndex < 0 || colIndex >= arg[0].length)
throw new IllegalArgumentException("Invalid index: " + colIndex
+ ".");
String[] result = new String[arg.length];
for (int i = 0; i < result.length; i++)
result[i] = arg[i][colIndex];
return result;
}
/**
* Gets a new string array with only the rows of arg1 that do
* not appear in arg2.
*
* @param arg1
* the string array to delete rows from that also appear in
* arg2
* @param arg2
* contains strings that are deleted from arg1
* @return a new string array object with deleted rows
* @throws IllegalArgumentException
* if (arg1 == null || arg2 == null)
*/
public static String[] getStringDiff(String[] arg1, String[] arg2) {
if (arg1 == null || arg2 == null)
throw new IllegalArgumentException("Argument was null.");
if (arg1.length == 0 || arg2.length == 0)
return arg1.clone();
ArrayList list = new ArrayList();
for (int i = 0; i < arg2.length; i++)
// fill the list to check
list.add(arg2[i]);
String[][] ret = toStringMatrix(arg1);
for (int i = 0; i < ret.length; i++)
if (list.contains(ret[i][0]))
ret = delRow(ret, i--);
if (ret.length == 0)
return new String[0];
return getStringCol(ret, 0);
}
/**
* Gets all rows of the array arg defined by
* startRow:endRow. The indices start with 0 as usual.
*
* @param arg
* the array to extract rows from
* @param startRow
* the index of the first row to extract (starting from 0)
* @param endRow
* the index of the last row to extract (starting from 0)
* @return a one dimensional string array with the row data
* @throws IllegalArgumentException
* if (arg == null) or
* if (arg.length == 0) or
* if (startRow > endRow) or if the indices
* are outside the valid array bounds or if rows of argument
* have different lengths
*/
public static String[][] getStringRows(String[][] arg, int startRow,
int endRow) {
if (arg == null)
throw new IllegalArgumentException("Argument was null.");
checkRowLengths(arg);
if (arg.length == 0)
throw new IllegalArgumentException("Argument has zero rows.");
if (startRow < 0 || startRow >= arg.length)
throw new IllegalArgumentException("Invalid start index: "
+ startRow + ".");
if (endRow < 0 || endRow >= arg.length)
throw new IllegalArgumentException("Invalid end index: " + endRow
+ ".");
if (endRow < startRow)
throw new IllegalArgumentException("Invalid indices [start:"
+ startRow + " > end:" + endRow + "].");
int r = endRow - startRow + 1;
String[][] newMat = new String[r][];
System.arraycopy(arg, startRow, newMat, 0, r);
return newMat;
}
/**
* Gets all columns of the array arg that have a nonzero
* corresponding element in index.
*
* @param arg
* the array to extract columns from
* @param index
* arg[0].length x 1 vector selecting columns from
* arg
*
* @return new array with the extracted columns,
* new String[0][0] if index contains only 0's, a
* copy of arg if index contains only
* nonzero elements
*
* @throws IllegalArgumentException
* if (arg == null || index == null) or
* if ((arg.length == 0 || arg[0].length == 0) && index.length > 0)
* or if (arg[0].length != index.length) or if
* rows of argument have different lengths
*/
public static String[][] selif(String[][] arg, int[] index) {
if (arg == null || index == null)
throw new IllegalArgumentException("Argument was null.");
if (index.length == 0 && (arg.length == 0 || arg[0].length == 0))
return new String[0][0];
if (arg.length == 0 || arg[0].length == 0)
throw new IllegalArgumentException("Argument was empty.");
checkRowLengths(arg);
if (arg[0].length != index.length)
throw new IllegalArgumentException(
"Columns of array do not match with dimension of index (array: "
+ arg[0].length + ", index: " + index.length + ").");
int num = UMatrix.getNonzeroIntCount(index);
// Nothing selected.
if (num == 0)
return new String[0][0];
// Everything selected.
if (num == arg[0].length)
return cloneStringArray(arg);
String[][] ret = new String[arg.length][num];
for (int i = 0, k = 0; i < index.length; i++)
if (index[i] != 0.0) {
for (int j = 0; j < ret.length; j++)
ret[j][k] = arg[j][i];
k++;
}
return ret;
}
/**
* Gets all rows of the array arg that have a nonzero
* corresponding element in index.
*
* @param arg
* the array to extract rows from
* @param index
* arg[0].length x 1 vector selecting rows from
* arg
*
* @return new array with the extracted rows, new String[0][0]
* if index contains only 0's, a copy of arg if
* index contains only nonzero elements
*
* @throws IllegalArgumentException
* if (arg == null || index == null) or
* if (arg.length == 0 || arg[0].length == 0) && index.length > 0)
* or if (arg.length != index.length) or if rows
* of argument have different lengths
*/
public static String[][] selRowsIf(String[][] arg, int[] index) {
if (arg == null || index == null)
throw new IllegalArgumentException("Argument was null.");
if (index.length == 0 && (arg.length == 0 || arg[0].length == 0))
return new String[0][0];
if (arg.length == 0 || arg[0].length == 0)
throw new IllegalArgumentException("Argument was empty.");
checkRowLengths(arg);
if (arg.length != index.length)
throw new IllegalArgumentException(
"Rows of array do not match with dimension of index (array: "
+ arg.length + ", index: " + index.length + ").");
int num = UMatrix.getNonzeroIntCount(index);
// Nothing selected.
if (num == 0)
return new String[0][0];
// Everything selected.
if (num == arg.length)
return cloneStringArray(arg);
String[][] ret = new String[num][arg[0].length];
for (int i = 0, k = 0; i < index.length; i++)
if (index[i] != 0.0)
ret[k++] = arg[i].clone();
return ret;
}
/**
* Gets a new string array with all elements arg that have a
* corresponding value in rowIndex that is != 0.
* arg and rowIndex must have the same
* dimension.
*
* @param arg
* the array to extract elements from
* @param rowIndex
* the index selecting elements from arg if
* rowIndex[i] != 0
*
* @return a one dimensional string array with the selected elements
*
* @throws IllegalArgumentException
* if (arg == null || rowIndex == null) or
* if (arg.length != rowIndex.length)
*/
public static String[] selRowsIf(String[] arg, int[] rowIndex) {
if (arg == null || rowIndex == null)
throw new IllegalArgumentException("Argument was null.");
if (arg.length != rowIndex.length)
throw new IllegalArgumentException(
"Rows of array do not match with dimension of index (array: "
+ arg.length + ", index: " + rowIndex.length + ").");
// Count the number of selected elements.
int count = 0;
for (int i = 0; i < rowIndex.length; i++)
if (rowIndex[i] > 0)
count++;
// Special cases.
if (count == 0)
return new String[0];
if (count == arg.length)
return arg.clone();
// Select elements and fill new array.
String[] ret = new String[count];
for (int i = 0, j = 0; i < arg.length; i++)
if (rowIndex[i] != 0)
ret[j++] = arg[i];
return ret;
}
/**
* Transforms a one-dimensional array into a K x 1 pseudo-two-dimensional
* array. This is sometimes needed to prepare arguments for methods that
* take String[][] instead of String[].
*
* @param arg
* the vector-like array to transform
* @return two-dimensional array with dimensions arg.length x 1
* or
*
* null if (arg == null)
* new String[0][0] if (arg.length == 0)
*
*/
public static String[][] toStringMatrix(String[] arg) {
if (arg == null)
return null;
if (arg.length == 0)
return new String[0][0];
String[][] m = new String[arg.length][1];
for (int i = 0; i < arg.length; i++)
m[i][0] = arg[i];
return m;
}
}
Ads help maintain this website.