Choosing the Right Data Structure in Ballerina: A Practical Guide

Faria KarimFaria Karim
4 min read

Introduction

Ballerina, a cloud-native programming language, brings together flexibility and simplicity, making it easy to work with data structures. This blog will cover essential data structures in Ballerina: lists, maps, records, and tables, along with practical examples for each. By the end, you'll be comfortable with choosing and using the right data structure for different needs in Ballerina.

Lists

Lists in Ballerina are similar to arrays, allowing you to store ordered collections of elements. Lists are typed, meaning all elements should be of the same type (e.g., int[] or string[]).

Creating and Using Lists

import ballerina/io;

public function main() {
    int[] numbers = [1, 2, 3, 4, 5];
    string[] fruits = ["apple", "banana", "cherry"];

    // Accessing elements
    int firstNumber = numbers[0]; // 1

    io:println(firstNumber);

    // Adding elements
    numbers.push(6);

    // Iterating through the list
    foreach var fruit in fruits {
        io:println(fruit);
    }

    // Printing the list
    io:println(numbers); // [1, 2, 3, 4, 5, 6]

    int removedNumber = numbers.remove(1);
    io:println(removedNumber); // [1, 2, 3, 4, 5, 6]
    io:println(numbers); // [1, 3, 4, 5, 6]
}

Key List Operations

  • push - Adds an element to the end of the list.
  • length - Returns the size of the list.

  • Index access (list[index]) - Retrieves an element at a specified position.

  • remove - Remove an element of a particular index and return the element

Lists are useful for maintaining a sequence of items where the order matters, like keeping track of items in a shopping cart.

Maps

Maps in Ballerina store key-value pairs, similar to dictionaries in other languages. They allow flexible data storage and easy retrieval of values by keys.

Creating and Using Maps

import ballerina/io;

public function main() {
    map<string> user = {name: "John", country: "USA"};

    // Accessing elements
    string? name = user["name"]; // "John"
    io:println(name);

    // Adding a new key-value pair
    user["email"] = "john@example.com";

    // Checking for a key
    boolean hasCountry = user.hasKey("country"); // true
    io:println(hasCountry);

    io:println(user); // {name: "John", country: "USA", email: "john@example.com"}
}

Key Map Operations

  • hasKey - Checks if a key exists.
  • Index access (map[key]) - Retrieves the value associated with the key.

  • Iteration - You can iterate over maps to access each key-value pair.

Maps are ideal for representing structured data with known fields, like a user profile with properties such as name, email, and country.

Records

Records in Ballerina are similar to structs or classes in other languages. They allow you to define a data structure with a fixed set of fields and types. Records are a great choice when you need a well-defined structure, such as representing a complex data entity.

Defining and Using Records

import ballerina/io;

type Person record {
    string name;
    int age;
    string city;
};

public function main() {
    Person person = {name: "Alice", age: 30, city: "New York"};

    // Accessing fields
    io:println(person.name); // "Alice"

    // Updating a field
    person.city = "Los Angeles";

    io:println(person); // {name: "Alice", age: 30, city: "Los Angeles"}
}

Key Record Features

  • Define fields with specific types.
  • Supports optional fields by using the ? syntax (e.g., string? phone).

  • You can also add default values to fields.

Records offer a way to work with more complex, structured data, making them perfect for situations where you need strict structure, like modelling an Employee or Product entity.

Tables

Tables in Ballerina are versatile structures for handling tabular data. They allow you to store data in rows with a defined schema, making tables suitable for managing structured data with a relational format.

Creating and Using Tables

import ballerina/io;

type Employee record {
    readonly int id;
    string name;
    string department;
};

public function main() {
      table<Employee> key(id) employees = table [
        {id: 1, name: "Alice", department: "Engineering"},
        {id: 2, name: "Bob", department: "Marketing"}
    ];

    // Adding a new row
    employees.add({id: 3, name: "Charlie", department: "HR"});

    // Filtering rows
    table<Employee> engineeringEmployees = from var emp in employees
                                           where emp.department == "Engineering"
                                           select emp;

    // Iterating over the table
    foreach var employee in engineeringEmployees {
        io:println(employee.name); // "Alice"
    }
}

Key Table Operations

  • add - Adds a new row to the table.
  • remove - Removes a row from the table.

  • Filtering using queries - Allows complex querying similar to SQL.

Tables are excellent for handling large sets of structured data, such as records from a database, where you may need to filter, sort, or group data.

Choosing the Right Data Structure

Here's a quick guide to choosing the appropriate data structure:

  • Lists: Use when you need an ordered collection of similar items.

  • Maps: Ideal for key-value pairs, where you need quick lookup by keys.

  • Records: Best for fixed structures with predefined fields, like data models.

  • Tables: Perfect for relational, tabular data that requires operations like filtering and sorting.

Conclusion:

Ballerina offers a range of data structures that simplify handling complex data for cloud-native applications. Understanding lists, maps, records, and tables will empower you to work more efficiently with Ballerina, and selecting the right data structure will make your code cleaner and more optimized for specific tasks.

0
Subscribe to my newsletter

Read articles from Faria Karim directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Faria Karim
Faria Karim

Currently, I am working as an "Associate Software Engineer" at "Kaz Software". I have completed my graduation from North South University in the year 2020 with the highest distinction. I always love to explore new ideas. I am a curious and self-motivated person. So, I always try to keep learning and share my ideas with other people. I enjoy problem-solving a lot. I have solved around 100+ problems in various online judges and I am also a three-star coder at Hackerrank. Moreover, I have participated in the ACM ICPC two times. I have completed the off-sight round of ACM ICPC of 2018. I have some basic knowledge of c/c++, Java, Javascript, Php, and Python. I have done several projects using these programming languages. I have hands-on experience on various backend frameworks like Node.js, Django, Flask, and Laravel. I have also used React.js as the front-end library for a few of my projects. Currently, I am more into React.js. For web-based projects, I have worked on both MySQL and NoSQL (MongoDB) as the database system. Machine learning is my another matter of interest. I have research experience in the fuzzy system. I have done a few projects using Tensorflow, Keras, CNN, and LSTM. Recently I have grown my interest in game development. I have built two games. One is using construct 2 and the another one is in Unity 3D. Side by side, I am also trying to figure out the things on ionic. In my free time, I mostly like to surf the internet, watch movies, and also love to do animations and illustrations using Powerpoint.