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.IntIntFloatFunc;
import java.util.function.IntPredicate;

import static Torello.Java.StrCSV.IAE_MESSAGE_MAXLENINNER;

class Float2D 
{
    static String toCSV(
            float[][] arr, IntIntFloatFunc<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();
    }
}