String_Encoder_Decoder
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © f4r33x

//@version=5

// @description String encoder and decoder to use in internal data tranfer in script calculations. In example script encode 125 values once and then decode them every candle. 
library("String_Encoder_Decoder")
import PineCoders/LibraryStopwatch/1 as sw
import f4r33x/fast_utils/2 as fu
// @function encode: encode some values into string 
// @param array of values  or values1, value2. etc: values to encode, must be stringified
// @returns encoded value
export encode(string[] arr_val) =>
	string res = na
	for val in arr_val
		if not na(val)
			res += val +';'
	res
export encode(string val1, string val2, string val3=na, string val4=na, string val5=na, string val6=na) =>
	arr_temp= array.from(val1, val2, val3, val4, val5, val6)
	string res = na
	for val in arr_temp
		if not na(val)
			res += val + ';'
	res
// @function decode: decode  into string 
// @param val  value to decode, must be stringified
// @returns decoded array of stringified values
export decode(string val) =>
	res = str.split(val, ';')
	array.pop(res)
	res














// PROOF OF CONCEPT
int_values_to_encode=array.from(15, 200, 99999, -100000, 0123456789)
float_values_to_encode=array.from(15.200, 200.99999, 99999.1, -100000, 0123456789.987654)
string_values_to_encode=array.from('tr', 'close', 'high', 'low', 'custom')

var arr_encoded = array.new_string(0)
mat_decoded = matrix.new<string>()

inp_number = input.int(defval= 0, title = 'number of values to decode every candle')
inp_refresh= input.int(defval= 0, title = 'refresh me')
// ENCODE ONCE DECODE EVERY CANDLE
if barstate.isfirst
    string val1 =na
    string val2 =na
    string val3 =na
	str_int_values_to_encode   =fu.stringify(int_values_to_encode)
	str_float_values_to_encode =fu.stringify(float_values_to_encode)
	for i=0 to array.size(string_values_to_encode)-1
        val1 := array.get(string_values_to_encode, i)
        for i=0 to array.size(str_int_values_to_encode)-1
            val2 := array.get(str_int_values_to_encode, i)
            for i=0 to array.size(str_float_values_to_encode)-1
                val3 := array.get(str_float_values_to_encode, i)
                array.push(arr_encoded, encode(val1,val2,val3))
for i = 0  to inp_number-1
	matrix.add_row(mat_decoded, i, decode(array.get(arr_encoded,i)))

res = array.size(arr_encoded)
str_res = str.tostring(matrix.row(mat_decoded, int(math.random(0,inp_number-1))))
[timePerBarInMs, totalTimeInMs, barsTimed, barsNotTimed] = sw.stopwatchStats()
msElapsed = sw.stopwatch()
if barstate.islast
    var table t = table.new(position.middle_right, 1, 1)
    var txt = str.tostring(timePerBarInMs, "ms/bar: #.######\n") +
              str.tostring(totalTimeInMs, "Total time (ms): #,###.######\n") + 
              str.tostring(barsTimed + barsNotTimed, "Bars analyzed: #\n") +
              str.tostring(res, "Number of encoded values : #.################\n")+
			  str_res	
              //str.tostring(matrix.row(mat_inouts,0))+ '\n' +
              //str.tostring(matrix.row(mat_inouts,1))
    table.cell(t, 0, 0, txt, bgcolor = color.yellow, text_halign = text.align_right)