I am just learning Ballerina (I imagine we all are still at this point). I am trying to do this JSON Exercism exercise. There are probably other ways to do it, but I would like to solve it in the following way, because I think this is generally useful for many situations:
public type FillUpEntry record {|
int employeeId;
int odometerReading;
decimal gallons;
decimal gasPrice;
|};
public type EmployeeFillUpSummary record {|
readonly int employeeId;
int gasFillUpCount;
decimal totalFuelCost;
decimal totalGallons;
int totalMilesAccrued;
|};
type IntermediarySummary record {|
readonly int employeeId;
int gasFillUpCount;
int firstOdometerReading;
int lastOdometerReading;
|};
public type EntryTable table<FillUpEntry>;
public type SummaryTable table<EmployeeFillUpSummary> key(employeeId);
type IntermediaryTable table<IntermediarySummary> key(employeeId);
(Not sure if I'll need the intermediary table... I thought I might because I need to keep track of the smallest and largest odometer reading to determine the total # of miles travelled.)
json|io:Error rawInput = io:fileReadJson(inputFilePath);
if rawInput is io:Error {
io:println(rawInput.message());
return ();
}
SummaryTable output;
IntermediaryTable intermediary;
EntryTable input = check rawInput.cloneWithType();
check from var item in input
do { // assuming that this is the first time I see the entry
// So I need some sort of `item.employeeId in intermediary.keys()` check. How can I do this??
intermediary.put({
employeeId: item.employeeId,
gasFillUpCount: 1,
firstOdometerReading: item.odometerReading,
lastOdometerReading: item.odometerReading
});
};
do { // assuming I have seen this entry before
intermediary.put({
employeeId: item.employeeId,
gasFillUpCount: <previous_value+1>,
firstOdometerReading: <previous_value>,
lastOdometerReading: item.odometerReading
});
};
I'm sure there are smarter ways to handle this, and to skip the intermediary altogether, but my key question is still important, I think:
intermediary
based upon the table record that I am currently iterating through.
You can check whether a particular record exists in a table using the hasKey()
function defined in the ballerina/lang.table
langlib module. Langlib modules are imported to the program implicitly, so there is no need to import them explicitly.
Are you looking for something like this?
json|io:Error rawInput = io:fileReadJson(inputFilePath);
if rawInput is io:Error {
io:println(rawInput.message());
return ();
}
SummaryTable output;
IntermediaryTable intermediary = table [];
EntryTable input = check rawInput.cloneWithType();
check from var item in input
do {
if intermediary.hasKey(item.employeeId) {
// assuming I have seen this entry before
intermediary.put({
employeeId: item.employeeId,
gasFillUpCount: <previous_value+1 > ,
firstOdometerReading: <previous_value>,
lastOdometerReading: item.odometerReading
});
} else {
// assuming that this is the first time I see the entry
intermediary.put({
employeeId: item.employeeId,
gasFillUpCount: 1,
firstOdometerReading: item.odometerReading,
lastOdometerReading: item.odometerReading
});
}
};