1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | package Torello.Java; import Torello.Java.Function.TriIntFunc; import java.util.function.IntPredicate; import static Torello.Java.StrCSV.IAE_MESSAGE_MAXLENINNER; class Int2D { static String toCSV( int[][] arr, TriIntFunc<String> toString, IntPredicate keepRow, boolean separateLines, Integer maxLengthInner, Integer maxLengthOuter ) { // maxLengthInner *MUST* be >= 7, since minimum-string-length is " [...]" // A value of 0 to 6 must throw an exception. // A negative value is treated the same as 'null' if ((maxLengthInner != null) && (maxLengthInner < 7) && (maxLengthInner >= 0)) throw new IllegalArgumentException (IAE_MESSAGE_MAXLENINNER.replace("TOK", maxLengthInner.toString())); else if ((maxLengthInner != null) && (maxLengthInner < 0)) maxLengthInner = null; StringBuilder sbOuter = new StringBuilder(); // Primary StringBuilder StringBuilder sbInner = new StringBuilder(); // StrinBuilder for the sub/inner arrays String s = null; // temp variable int i = 0; // outer-loop loop-counter int numRows = 0; // Count sub-arrays // If the value passed to 'maxLengthOuter' is negative, treat it the same as 'null' // SPECIFICALLY: No Max Length. if ((maxLengthOuter != null) && (maxLengthOuter < 0)) maxLengthOuter = null; sbOuter.append('['); for (i=0; i < arr.length; i++) { // The "Keep Row" Predicate is used to check whether a sub-array should even be // included at all. If "Keep Row" exists, and it rejects the outer array index, // then the entire row itself should be skipped. if ((keepRow != null) && (! keepRow.test(i))) continue; numRows++; if ((maxLengthOuter != null) && (numRows > maxLengthOuter)) break; int j = 0; // System.out.println("end: " + end + ",\ti: " + i + ",\tj: " + j); // The purpose to this sub-loop is such that there is a "provided user option" where // the 'toString-lambda' may return a ZERO-LENGTH-STRING, and when this happens, the // array-location that resulted in a ZERO-LENGTH-STRING shall be ignored/skipped // completely. if (toString != null) while ( (j < arr[i].length) && ((s = toString.apply(i, j, arr[i][j])).length() == 0) ) j++; else s = "" + arr[i][j]; // If "separateLines" be sure to add a newline. if (separateLines) sbOuter.append('\n'); // Add the opening brackets to this new sub-array that was just computed. sbInner.append(" [" + s); j++; // Main Printing Loop while (j < arr[i].length) { if (toString != null) { if ((s = toString.apply(i, j, arr[i][j++])).length() > 0) sbInner.append(", " + s); } else sbInner.append(", " + arr[i][j++]); if ((maxLengthInner != null) && (sbInner.length() > maxLengthInner)) break; } // NOTE: The '+ 1' is needed because, as of yet, the trailing ']' has not been added. if ((maxLengthInner != null) && ((sbInner.length() + 1) > maxLengthInner)) { int pos = sbInner.length() - 4; char c = sbInner.charAt(pos); while ((c != ',') && (c != '[')) c = sbInner.charAt(--pos); sbInner.setLength(pos+1); sbInner.append((c == '[') ? "..." : " ..."); } sbInner.append(']'); sbOuter.append(sbInner.toString()); sbInner.setLength(0); } // This shall only execute if the if (i < arr.length) sbOuter.append((separateLines ? "\n" : "") + " ..."); sbOuter.append(separateLines ? "\n]" : " ]"); return sbOuter.toString(); } } |