PINE LIBRARY

Dictionary/Object Library

Updated
This Library is aimed to mitigate the limitation of Pinescript having only one structured data type which is only arrays.
It lacks data types like Dictionaries(in Python) or Object (in JS) that are standard for other languages. Tuples do exist, but it hardly solves any problem.
Working only with Arrays could be overwhelming if your codebase is large. I looked for alternatives to arrays but couldn't find any library.
So I coded it myself and it's been working good for me. So I wanted to share it with you all.

What does it do:
==================
If you are familiar with Python or Javascript, this library tries to immimate Object/Dictonary like structure with Key Value Pairs.
For Example:

object= {name:"John Doe", age: 28 , org: "PineCoders"}

And then it also tries to immitate the Array of Objects (I call it Stack)
like this:
stack= Array({name:"John Doe", age: 28 , org: "PineCoders"},
{name:"Adam Smith", age: 32 , org: "PineCoders"},
{name:"Paragjyoti Deka", age: 25 , org: "PineCoders"})

So there are basically two ideas: Objects and Stacks.

But it looks whole different in Pinescript for obvious reasons.

Limitation:

The major limitation I couldn't overcome was that, for all of the values: both input and return values for properties will be of string type.
This is due to the limiation of Pinecsript that there is no way to return a value on a if-else statement dynamically with different data types.
And as the input data type must be explicitly defined when exporting the library functions, only string inputs are allowed.
Now that doesn't mean you won't be able to use integer, float or boolens, you just need to pass the string value for it using str.tostring() method.
And the output for the getter functions will be in strings as well. But I have added some type conversion methods that you could use from this library itself.
From String to Float, String To Integer and String to Boolean: these three methods are included in this library.

So basically the whole library is based on a manipulatiion of Array of strings under the hood.

///////////////
Usage
///////////////

Import the library using this statement:

import paragjyoti2012/STR_Dict_Lib/4 as DictLib

Objects

First define an object using this method:

for eample:

object1= DictLib.init("name=John,age=26,org=")

This is similar to
object1= {name:"John",age:"26", org:""} in JS or Python

Just like we did here in for "org", you can set initital value to "". But remember to pass string values, even for a numerical properties, like here in "age".
You can use "age="+str.tostring(age). If you find it tedious, you can always add properties later on using .set() method.

So it could also be initiated like this
object= DictLib.init("name=John")
and later on
DictLib.set(object1,"age", str.toString(age))
DictLib.set(object1,"org", "PineCoders")


The getter function looks like this

age= DictLib.get(object1,"age")
name=DictLib.get(object1,"name")

The first argument for all methods .get, .set, and .remove is the pointer (name of the object).

///////////////////////////
Array Of Objects (Stacks)
///////////////////////////


As I mentioned earlier, I call the array of objects as Stack.

Here's how to initialize a Stack.

stack= DictLib.initStack(object1)

The .initStack() method takes an object pointer as argument. It simply converts the array into a string and pushes it into the newly created stack.

Rest of all the methods for Stacks, takes the stack pointer as it's first arument.

For example:

DictLib.pushStack(stack,object2)

The second argument here is the object pointer. It adds the object to it's stack. Although it might feel like a two dimentional array, it's actually an one dimentional array with string values.
Under the hood, it looks like this ["name=John,age=26,org=Pinecoders",
"name=Adam,age=35,org=Pinecoders"]

////////////////////
Methods
////////////////////

For Objects
-------------------

init() : Initializes the object.

params: (string) e.g
returns: The object ([The object is actually an array of strings. So the .init() method, basically returns an array of strings])

example:
object1=DictLib.init("name=John,age=26,org=")

...................

get() : Returns the value for given property
params: (string[] object_pointer, string property)
returns: string

example:
age= DictLib.get(object1,"age")

.......................

set() : Adds a new property or updates an existing property
params: (string[] object_pointer, string property, string value)
returns: void

example:
DictLib.set(object1,"age", str.tostring(29))

........................

remove() : Removes a property from the object
params : (string[] object_pointer, string property)
returns: void

example:
DictLib.set(object1,"org")

........................


For Array Of Objects (Stacks)
-------------------------------

initStack() : Initializes the stack.

params: (string[] object_pointer) e.g
returns: The Stack

example:
stack= DictLib.initStack(object1)

...................

pushToStack() : Adds an object at at last index of the stack
params: (string[] stack_pointer, string[] object_pointer)
returns: void

example:
DictLib.pushToStack(stack,object2)

.......................

popFromStack() : Removes the last object from the stack
params: (string[] stack_pointer)
returns: void

example:
DictLib.popFromStack(stack)

.......................

insertToStack() : Adds an object at at the given index of the stack
params: (string[] stack_pointer, string[] object_pointer, int index)
returns: void

example:
DictLib.insertToStack(stack,object3,1)

.......................

removeFromStack() : Removes the object from the given index of the stack
params: (string[] stack_pointer, int index)
returns: void

example:
DictLib.removeFromStack(stack,2)

.......................

getElement () : Returns the value for given property from an object in the stack (index must be given)
params: (string[] stack_pointer, int index, string property)
returns: string

example:
ageFromObject1= DictLib.getElement(stack,0,"age")

.......................

setElement() : Updates an existing property of an object in the stack (index must be given)
params: (string[] stack_pointer, int index, string property, string value)
returns: void

example:
DictLib.setElement(stack,0,"age", str.tostring(32))

........................

includesElement() : Checks if any object exists in the stack with the given property-value pair
params : (string[] stack_pointer, string property, string value)
returns : Boolean

example:
doesExist= DictLib.includesElement(stack,"org","PineCoders")

........................

searchStack() : Search for a property-value pair in the stack and returns it's index
params: (stringp[] stack_pointer, string property, string value)
returns: int (-1 if doesn't exist)

example:
index= DictLib.searchElement(stack,"org","PineCoders")

///////////////////////
Type Conversion Methods
///////////////////////


strToFloat() : Converts String value to Float
params: (string value)
returns: float

example:
floatVal= DictLib.strToFloat("57.96")

.............................

strToInt() : Converts String value to Integer
params: (string value)
returns: int

example:
intVal= DictLib.strToFloat("45")
.............................

strToBool() : Converts String value to Boolean
params: (string value)
returns: boolean

example:
boolVal= DictLib.strToBool("true")
.............................


Points to remember
...............

1. Always pass string values as arguments.
2. The return values will be of type string, so convert them before to avoid typecasting conflict.
3. Horses can't vomit.

More Informations
====================

Yes, You can store this objects and stacks for persisting through the iterations of a script across successive bars.
You just need to set the variable using "var" keyword. Remember this objects and stacks are just arrays,
so any methods and properties an array have it pinescript, would be applicable for objects and stacks.

It can also be used in security functions without any issues for MTF Analysis.

If you have any suggestions or feedback, please comment on the thread, I would surely be happy to help.

Release Notes
v2
Release Notes
v3

Added: 6 new getter methods.

This getter methods will return already type-converted values instead of string values.
For example: If your property is of type: integer, then call .getInt method instead(For objects) or .getIntElement method instead (for Stacks).
It will reduce the extra step of converting the type by yourself.

The plain .get method and .getElement method will always return string value. And for setter methods, you still need to pass string values.

getFloat() : Returns the float value for given property
params: (string object_pointer, string property)
returns: float

example:
rsi= DictLib.get(object1,"rsi")

getInt() : returns Integer value for your property

getBool() : returns Boolean value for your property

////////////////
For Stacks
/////////////////

getIntElement () : Returns the integer value for given property from an object in the stack (index must be given)
params: (string stack_pointer, int index, string property)
returns: int

example:
ageFromObject1= DictLib.getElement(stack,0,"age")

getFloatElement() : Returns float value for your property

getBoolElement() : Returns Boolean value for your property

Release Notes
v4

Removed:
strToFloat()

strToInt()

strToBool()

Removed these type conversion methods as Pinescript officially supports str.tonumber() method
Release Notes
v5
Release Notes
v6
Release Notes
v7

Added:
updateStack()

setFloat()

setInt()

setBool()

setFloatElement()

setIntElement()

setBoolElement()
arraysclassdictionaryformattingjavascriptobjectoopprogrammingpythonstringstuple

Pine library

In true TradingView spirit, the author has published this Pine code as an open-source library so that other Pine programmers from our community can reuse it. Cheers to the author! You may use this library privately or in other open-source publications, but reuse of this code in a publication is governed by House rules.

Disclaimer