/*
 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 *

* @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.