Itab Exercises (#175)

This commit is contained in:
Rich Heilman
2022-08-10 08:48:54 -04:00
committed by GitHub
parent a67bec4ce3
commit 4a7d18105c
27 changed files with 1058 additions and 41 deletions

View File

@@ -594,10 +594,7 @@
"exclude": [],
"severity": "Error"
},
"no_inline_in_optional_branches": {
"exclude": [],
"severity": "Error"
},
"no_inline_in_optional_branches": false,
"no_public_attributes": {
"exclude": [],
"severity": "Error",

View File

@@ -38,6 +38,30 @@
"prerequisites": [],
"difficulty": 1
},
{
"slug": "itab-aggregation",
"name": "ITAB Aggregation",
"uuid": "b31ecd5d-939b-44a5-80ac-798787c2dde3",
"practices": [],
"prerequisites": [],
"difficulty": 1
},
{
"slug": "itab-combination",
"name": "ITAB Combination",
"uuid": "859b8764-71d0-461a-a30d-c2e0fee75ced",
"practices": [],
"prerequisites": [],
"difficulty": 1
},
{
"slug": "itab-nesting",
"name": "ITAB Nesting",
"uuid": "9aad92ad-1522-4612-8640-1545b7167857",
"practices": [],
"prerequisites": [],
"difficulty": 1
},
{
"slug": "hello-world",
"name": "Hello, World!",

View File

@@ -0,0 +1,44 @@
# Instructions
Learn how to aggregate and group data within an ABAP internal table.
You class will be given an internal table named `initial_numbers`. It has two columns: `GROUP` and `NUMBER`.
```abap
TYPES: BEGIN OF initial_numbers_type,
group TYPE group,
number TYPE i,
END OF initial_numbers_type,
initial_numbers TYPE STANDARD TABLE OF initial_numbers_type WITH EMPTY KEY.
```
The data in this table consists of three groups - A, B, and C. There are multiple records in each group.
| GROUP | NUMBER |
| --- | ----------- |
| A | 10 |
| B | 5 |
| A | 6 |
| C | 22 |
| A | 13 |
| C | 500 |
Your task is to return an internal table with one record per group. This record should contain the number of records in the original table per group (`COUNT`), the sum of all `NUMBER` values in this group (`SUM)`, the minimum value in the group (`MIN`), the maximum value in the group (`MAX`) and the average of all values in that group (`AVERAGE`).
The expected return table has the following definition:
```abap
TYPES: BEGIN OF aggregated_data_type,
group TYPE group,
count TYPE i,
sum TYPE i,
min TYPE i,
max TYPE i,
average TYPE f,
END OF aggregated_data_type,
aggregated_data TYPE STANDARD TABLE OF aggregated_data_Type WITH EMPTY KEY.
```
## Bonus
There are many ways to accomplish this task in ABAP. How efficiently can you complete the task? Can you do this while only reading each record in the table once?

View File

@@ -0,0 +1,13 @@
{
"blurb": "Given a certain internal table, aggregate the data while also grouping it",
"authors": ["jung-thomas"],
"contributors": [
],
"files": {
"solution": ["zcl_itab_aggregation.clas.abap"],
"test": ["zcl_itab_aggregation.clas.testclasses.abap"],
"example": [".meta/zcl_itab_aggregation.clas.abap"]
},
"source": "ABAP Internal Tables",
"source_url": "https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenitab.htm"
}

View File

@@ -0,0 +1,56 @@
CLASS zcl_itab_aggregation DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES group TYPE c LENGTH 1.
TYPES: BEGIN OF initial_numbers_type,
group TYPE group,
number TYPE i,
END OF initial_numbers_type,
initial_numbers TYPE STANDARD TABLE OF initial_numbers_type WITH EMPTY KEY.
TYPES: BEGIN OF aggregated_data_type,
group TYPE group,
count TYPE i,
sum TYPE i,
min TYPE i,
max TYPE i,
average TYPE f,
END OF aggregated_data_type,
aggregated_data TYPE STANDARD TABLE OF aggregated_data_type WITH EMPTY KEY.
METHODS perform_aggregation
IMPORTING
initial_numbers TYPE initial_numbers
RETURNING
VALUE(aggregated_data) TYPE aggregated_data.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_itab_aggregation IMPLEMENTATION.
METHOD perform_aggregation.
LOOP AT initial_numbers REFERENCE INTO DATA(initial_number)
GROUP BY ( key = initial_number->group count = GROUP SIZE )
ASCENDING
REFERENCE INTO DATA(group_key).
APPEND INITIAL LINE TO aggregated_data REFERENCE INTO DATA(aggregated_item).
aggregated_item->group = group_key->key.
aggregated_item->count = group_key->count.
aggregated_item->min = 9999999.
LOOP AT GROUP group_key REFERENCE INTO DATA(group_item).
aggregated_item->sum = aggregated_item->sum + group_item->number.
aggregated_item->min = nmin( val1 = aggregated_item->min
val2 = group_item->number ).
aggregated_item->max = nmax( val1 = aggregated_item->max
val2 = group_item->number ).
ENDLOOP.
aggregated_item->average = aggregated_item->sum / aggregated_item->count.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DEVC" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DEVC>
<CTEXT>Exercism: Interal Table Aggregation</CTEXT>
</DEVC>
</asx:values>
</asx:abap>
</abapGit>

View File

@@ -0,0 +1,41 @@
CLASS zcl_itab_aggregation DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES group TYPE c LENGTH 1.
TYPES: BEGIN OF initial_numbers_type,
group TYPE group,
number TYPE i,
END OF initial_numbers_type,
initial_numbers TYPE STANDARD TABLE OF initial_numbers_type WITH EMPTY KEY.
TYPES: BEGIN OF aggregated_data_type,
group TYPE group,
count TYPE i,
sum TYPE i,
min TYPE i,
max TYPE i,
average TYPE f,
END OF aggregated_data_type,
aggregated_data TYPE STANDARD TABLE OF aggregated_data_type WITH EMPTY KEY.
METHODS perform_aggregation
IMPORTING
initial_numbers TYPE initial_numbers
RETURNING
VALUE(aggregated_data) TYPE aggregated_data.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_itab_aggregation IMPLEMENTATION.
METHOD perform_aggregation.
" add solution here
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,166 @@
CLASS ltcl_itab_aggregation DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL.
PRIVATE SECTION.
DATA cut TYPE REF TO zcl_itab_aggregation.
METHODS setup.
METHODS empty FOR TESTING RAISING cx_static_check.
METHODS one_row FOR TESTING RAISING cx_static_check.
METHODS one_group FOR TESTING RAISING cx_static_check.
METHODS two_groups FOR TESTING RAISING cx_static_check.
METHODS negative FOR TESTING RAISING cx_static_check.
METHODS negative_zero FOR TESTING RAISING cx_static_check.
METHODS negative_count FOR TESTING RAISING cx_static_check.
METHODS aggregation FOR TESTING RAISING cx_static_check.
METHODS aggregation_extended FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltcl_itab_aggregation IMPLEMENTATION.
METHOD setup.
cut = NEW zcl_itab_aggregation( ).
ENDMETHOD.
METHOD empty.
cl_abap_unit_assert=>assert_equals(
act = cut->perform_aggregation( VALUE #( ) )
exp = VALUE zcl_itab_aggregation=>aggregated_data( ) ).
ENDMETHOD.
METHOD one_row.
DATA(actual_values) = VALUE zcl_itab_aggregation=>initial_numbers(
( group = 'A' number = 10 ) ).
DATA(expected_values) = VALUE zcl_itab_aggregation=>aggregated_data(
( group = 'A' count = 1 sum = 10 min = 10 max = 10 average = 10 ) ).
cl_abap_unit_assert=>assert_equals(
act = cut->perform_aggregation( actual_values )
exp = expected_values ).
ENDMETHOD.
METHOD negative.
DATA(actual_values) = VALUE zcl_itab_aggregation=>initial_numbers(
( group = 'A' number = 10 )
( group = 'A' number = -6 )
( group = 'A' number = 13 ) ).
DATA(expected_values) = VALUE zcl_itab_aggregation=>aggregated_data(
( group = 'A' count = 3 sum = 17 min = -6 max = 13 average = 17 / 3 ) ).
cl_abap_unit_assert=>assert_equals(
act = cut->perform_aggregation( actual_values )
exp = expected_values ).
ENDMETHOD.
METHOD negative_zero.
DATA(actual_values) = VALUE zcl_itab_aggregation=>initial_numbers(
( group = 'A' number = 10 )
( group = 'A' number = -10 ) ).
DATA(expected_values) = VALUE zcl_itab_aggregation=>aggregated_data(
( group = 'A' count = 2 sum = 0 min = -10 max = 10 average = 0 / 2 ) ).
cl_abap_unit_assert=>assert_equals(
act = cut->perform_aggregation( actual_values )
exp = expected_values ).
ENDMETHOD.
METHOD negative_count.
DATA(actual_values) = VALUE zcl_itab_aggregation=>initial_numbers(
( group = 'A' number = 10 )
( group = 'B' number = 5 )
( group = 'A' number = 6 )
( group = 'C' number = 22 )
( group = 'A' number = 13 )
( group = 'C' number = 500 ) ).
DATA(aggregated_data) = cut->perform_aggregation( actual_values ).
LOOP AT aggregated_data REFERENCE INTO DATA(aggregated_item).
cl_abap_unit_assert=>assert_differs(
act = aggregated_item->count
exp = 0 ).
ENDLOOP.
ENDMETHOD.
METHOD one_group.
DATA(actual_values) = VALUE zcl_itab_aggregation=>initial_numbers(
( group = 'A' number = 10 )
( group = 'A' number = 6 )
( group = 'A' number = 13 ) ).
DATA(expected_values) = VALUE zcl_itab_aggregation=>aggregated_data(
( group = 'A' count = 3 sum = 29 min = 6 max = 13 average = 29 / 3 ) ).
cl_abap_unit_assert=>assert_equals(
act = cut->perform_aggregation( actual_values )
exp = expected_values ).
ENDMETHOD.
METHOD two_groups.
DATA(actual_values) = VALUE zcl_itab_aggregation=>initial_numbers(
( group = 'A' number = 10 )
( group = 'B' number = 5 ) ).
DATA(expected_values) = VALUE zcl_itab_aggregation=>aggregated_data(
( group = 'A' count = 1 sum = 10 min = 10 max = 10 average = 10 )
( group = 'B' count = 1 sum = 5 min = 5 max = 5 average = 5 ) ).
cl_abap_unit_assert=>assert_equals(
act = cut->perform_aggregation( actual_values )
exp = expected_values ).
ENDMETHOD.
METHOD aggregation.
DATA(actual_values) = VALUE zcl_itab_aggregation=>initial_numbers(
( group = 'A' number = 10 )
( group = 'B' number = 5 )
( group = 'A' number = 6 )
( group = 'C' number = 22 )
( group = 'A' number = 13 )
( group = 'C' number = 500 ) ).
DATA(expected_values) = VALUE zcl_itab_aggregation=>aggregated_data(
( group = 'A' count = 3 sum = 29 min = 6 max = 13 average = 29 / 3 )
( group = 'B' count = 1 sum = 5 min = 5 max = 5 average = 5 / 1 )
( group = 'C' count = 2 sum = 522 min = 22 max = 500 average = 522 / 2 ) ).
cl_abap_unit_assert=>assert_equals(
act = cut->perform_aggregation( actual_values )
exp = expected_values ).
ENDMETHOD.
METHOD aggregation_extended.
DATA(actual_values) = VALUE zcl_itab_aggregation=>initial_numbers(
( group = 'D' number = 10 )
( group = 'E' number = 10 )
( group = 'D' number = 6 )
( group = 'F' number = 22 )
( group = 'D' number = 13 )
( group = 'F' number = 500 ) ).
DATA(expected_values) = VALUE zcl_itab_aggregation=>aggregated_data(
( group = 'D' count = 3 sum = 29 min = 6 max = 13 average = 29 / 3 )
( group = 'E' count = 1 sum = 10 min = 10 max = 10 average = 10 / 1 )
( group = 'F' count = 2 sum = 522 min = 22 max = 500 average = 522 / 2 ) ).
cl_abap_unit_assert=>assert_equals(
act = cut->perform_aggregation( actual_values )
exp = expected_values ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOCLASS>
<CLSNAME>ZCL_ITAB_AGGREGATION</CLSNAME>
<LANGU>E</LANGU>
<DESCRIPT>Exercism: Interal Table Aggregation</DESCRIPT>
<STATE>1</STATE>
<CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT>
<UNICODE>X</UNICODE>
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>

View File

@@ -2,16 +2,16 @@
Learn the basics about ABAP internal tables.
You class has an internal table named `initial_data`. It has three columns: `GROUP`, `NUMBER`, and `DESCRIPTION`.
Your class has an internal table named `initial_data`. It has three columns: `GROUP`, `NUMBER`, and `DESCRIPTION`.
```abap
TYPES group TYPE c LENGTH 1.
TYPES: BEGIN OF initial_type,
group TYPE group,
number TYPE i,
description TYPE string,
END OF initial_type,
initial_data TYPE STANDARD TABLE OF initial_type WITH EMPTY KEY.
TYPES group TYPE c LENGTH 1.
TYPES: BEGIN OF initial_type,
group TYPE group,
number TYPE i,
description TYPE string,
END OF initial_type,
initial_data TYPE STANDARD TABLE OF initial_type WITH EMPTY KEY.
```
## Step 1
@@ -37,7 +37,7 @@ Next implement the method `add_to_itab` to add a record to the end of the intern
## Step 3
Now please sort the internal in the method `sort_itab` with the `GROUP` column in alphabetical order and the `NUMBER` column in descending order.
Now please sort the internal table in the method `sort_itab` with the `GROUP` column in alphabetical order and the `NUMBER` column in descending order.
## Step 4

View File

@@ -3,7 +3,6 @@ CLASS zcl_itab_basics DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES group TYPE c LENGTH 1.
TYPES: BEGIN OF initial_type,
@@ -14,27 +13,28 @@ CLASS zcl_itab_basics DEFINITION
itab_data_type TYPE STANDARD TABLE OF initial_type WITH EMPTY KEY.
METHODS fill_itab
RETURNING
VALUE(initial_data) TYPE itab_data_type.
RETURNING
VALUE(initial_data) TYPE itab_data_type.
METHODS add_to_itab
RETURNING
VALUE(updated_data) TYPE itab_data_type.
IMPORTING initial_data TYPE itab_data_type
RETURNING
VALUE(updated_data) TYPE itab_data_type.
METHODS sort_itab
RETURNING
VALUE(updated_data) TYPE itab_data_type.
IMPORTING initial_data TYPE itab_data_type
RETURNING
VALUE(updated_data) TYPE itab_data_type.
METHODS search_itab
RETURNING
VALUE(result_index) TYPE i.
IMPORTING initial_data TYPE itab_data_type
RETURNING
VALUE(result_index) TYPE i.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_itab_basics IMPLEMENTATION.
METHOD fill_itab.
initial_data = VALUE #(
@@ -47,19 +47,19 @@ CLASS zcl_itab_basics IMPLEMENTATION.
ENDMETHOD.
METHOD add_to_itab.
updated_data = fill_itab( ).
updated_data = initial_data.
APPEND
VALUE #( group = 'A' number = 19 description = 'Group A-4' )
TO updated_data.
ENDMETHOD.
METHOD sort_itab.
updated_data = add_to_itab( ).
updated_data = initial_data.
SORT updated_data BY group ASCENDING number DESCENDING.
ENDMETHOD.
METHOD search_itab.
DATA(temp_data) = sort_itab( ).
DATA(temp_data) = initial_data.
READ TABLE temp_data WITH KEY number = 6 TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
result_index = sy-tabix.

View File

@@ -14,20 +14,23 @@ CLASS zcl_itab_basics DEFINITION
itab_data_type TYPE STANDARD TABLE OF initial_type WITH EMPTY KEY.
METHODS fill_itab
RETURNING
VALUE(initial_data) TYPE itab_data_type.
RETURNING
VALUE(initial_data) TYPE itab_data_type.
METHODS add_to_itab
RETURNING
VALUE(updated_data) TYPE itab_data_type.
IMPORTING initial_data TYPE itab_data_type
RETURNING
VALUE(updated_data) TYPE itab_data_type.
METHODS sort_itab
RETURNING
VALUE(updated_data) TYPE itab_data_type.
IMPORTING initial_data TYPE itab_data_type
RETURNING
VALUE(updated_data) TYPE itab_data_type.
METHODS search_itab
RETURNING
VALUE(result_index) TYPE i.
IMPORTING initial_data TYPE itab_data_type
RETURNING
VALUE(result_index) TYPE i.
PROTECTED SECTION.
PRIVATE SECTION.
@@ -41,17 +44,17 @@ CLASS zcl_itab_basics IMPLEMENTATION.
ENDMETHOD.
METHOD add_to_itab.
updated_data = fill_itab( ).
updated_data = initial_data.
"add solution here
ENDMETHOD.
METHOD sort_itab.
updated_data = add_to_itab( ).
updated_data = initial_data.
"add solution here
ENDMETHOD.
METHOD search_itab.
DATA(temp_data) = sort_itab( ).
DATA(temp_data) = initial_data.
"add solution here
ENDMETHOD.

View File

@@ -3,8 +3,11 @@ CLASS ltcl_itab_basics DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT
DATA cut TYPE REF TO zcl_itab_basics.
METHODS setup.
METHODS test_fill_itab FOR TESTING RAISING cx_static_check.
METHODS test_add_to_itab_empty FOR TESTING RAISING cx_static_check.
METHODS test_add_to_itab FOR TESTING RAISING cx_static_check.
METHODS test_sort_itab_empty FOR TESTING RAISING cx_static_check.
METHODS test_sort_itab FOR TESTING RAISING cx_static_check.
METHODS test_search_itab_empty FOR TESTING RAISING cx_static_check.
METHODS test_search_itab FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltcl_itab_basics IMPLEMENTATION.
@@ -15,6 +18,9 @@ CLASS ltcl_itab_basics IMPLEMENTATION.
METHOD test_fill_itab.
DATA(actual) = cut->fill_itab( ).
cl_abap_unit_assert=>assert_not_initial( actual ).
DATA(expected_values) = VALUE zcl_itab_basics=>itab_data_type(
( group = 'A' number = 10 description = 'Group A-2' )
( group = 'B' number = 5 description = 'Group B' )
@@ -29,8 +35,17 @@ CLASS ltcl_itab_basics IMPLEMENTATION.
ENDMETHOD.
METHOD test_add_to_itab_empty.
cl_abap_unit_assert=>assert_equals(
act = lines( cut->add_to_itab( VALUE #( ) ) )
exp = 1 ).
ENDMETHOD.
METHOD test_add_to_itab.
DATA(expected_values) = VALUE zcl_itab_basics=>itab_data_type(
( group = 'A' number = 10 description = 'Group A-2' )
( group = 'B' number = 5 description = 'Group B' )
@@ -41,8 +56,15 @@ CLASS ltcl_itab_basics IMPLEMENTATION.
( group = 'A' number = 19 description = 'Group A-4' ) ).
cl_abap_unit_assert=>assert_equals(
act = cut->add_to_itab( )
act = cut->add_to_itab( cut->fill_itab( ) )
exp = expected_values ).
ENDMETHOD.
METHOD test_sort_itab_empty.
cl_abap_unit_assert=>assert_equals(
act = cut->sort_itab( VALUE #( ) )
exp = VALUE zcl_itab_basics=>itab_data_type( ) ).
ENDMETHOD.
METHOD test_sort_itab.
@@ -56,14 +78,19 @@ CLASS ltcl_itab_basics IMPLEMENTATION.
( group = 'C' number = 22 description = 'Group C-1' ) ).
cl_abap_unit_assert=>assert_equals(
act = cut->sort_itab( )
act = cut->sort_itab( cut->add_to_itab( cut->fill_itab( ) ) )
exp = expected_values ).
ENDMETHOD.
METHOD test_search_itab_empty.
cl_abap_unit_assert=>assert_equals(
act = cut->search_itab( VALUE #( ) )
exp = 0 ).
ENDMETHOD.
METHOD test_search_itab.
cl_abap_unit_assert=>assert_equals(
act = cut->search_itab( )
act = cut->search_itab( cut->sort_itab( cut->add_to_itab( cut->fill_itab( ) ) ) )
exp = 4 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,54 @@
# Instructions
Learn how to combine data from two different internal tables into one result internal table.
Your class will be given two internal tables which contain two completely different datasets, ALPHAS and NUMS
```abap
TYPES: BEGIN OF alphatab_type,
cola TYPE string,
colb TYPE string,
colc TYPE string,
END OF alphatab_type.
TYPES: alphas TYPE STANDARD TABLE OF alphatab_type.
TYPES: BEGIN OF numtab_type,
col1 TYPE string,
col2 TYPE string,
col3 TYPE string,
END OF numtab_type.
TYPES: nums TYPE STANDARD TABLE OF numtab_type.
```
The data in the ALPHA table is as shown below.
| COLA | COLB | COLC |
| --- | --- | --- |
| A | B | C |
| D | E | F |
| G | H | I |
The data in the NUMS table is as shown below.
| COL1 | COL2 | COL3 |
| --- | --- | --- |
| 1 | 2 | 3 |
| 4 | 5 | 6 |
| 7 | 8 | 9 |
Your task is to return an internal table with records which combine the values of each cell of interal table ALPHAS and internal table NUMS together. For example the value of the first column of the first row of the COMBINED_DATA internal table should be "A1".
The expected return table has the following definition:
```abap
TYPES: BEGIN OF combined_data_type,
colx TYPE string,
coly TYPE string,
colz TYPE string,
END OF combined_data_type.
TYPES: combined_data TYPE STANDARD TABLE OF combined_data_type WITH EMPTY KEY.
```
## Bonus
There are many ways to accomplish this task in ABAP. How efficiently can you complete the task?

View File

@@ -0,0 +1,13 @@
{
"blurb": "Given two different internal tables, combine the values of each table together into one internal table",
"authors": ["rich-heilman"],
"contributors": [
],
"files": {
"solution": ["zcl_itab_combination.clas.abap"],
"test": ["zcl_itab_combination.clas.testclasses.abap"],
"example": [".meta/zcl_itab_combination.clas.abap"]
},
"source": "ABAP Internal Tables",
"source_url": "https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenitab.htm"
}

View File

@@ -0,0 +1,57 @@
CLASS zcl_itab_combination DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES: BEGIN OF alphatab_type,
cola TYPE string,
colb TYPE string,
colc TYPE string,
END OF alphatab_type.
TYPES alphas TYPE STANDARD TABLE OF alphatab_type.
TYPES: BEGIN OF numtab_type,
col1 TYPE string,
col2 TYPE string,
col3 TYPE string,
END OF numtab_type.
TYPES nums TYPE STANDARD TABLE OF numtab_type.
TYPES: BEGIN OF combined_data_type,
colx TYPE string,
coly TYPE string,
colz TYPE string,
END OF combined_data_type.
TYPES combined_data TYPE STANDARD TABLE OF combined_data_type WITH EMPTY KEY.
METHODS perform_combination
IMPORTING
alphas TYPE alphas
nums TYPE nums
RETURNING
VALUE(combined_data) TYPE combined_data.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_itab_combination IMPLEMENTATION.
METHOD perform_combination.
LOOP AT alphas REFERENCE INTO DATA(alpha).
APPEND INITIAL LINE TO combined_data REFERENCE INTO DATA(combined_values).
READ TABLE nums REFERENCE INTO DATA(num) INDEX sy-tabix.
IF sy-subrc = 0.
combined_values->colx = alpha->cola && num->col1.
combined_values->coly = alpha->colb && num->col2.
combined_values->colz = alpha->colc && num->col3.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DEVC" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DEVC>
<CTEXT>Exercism: Interal Table Combination</CTEXT>
</DEVC>
</asx:values>
</asx:abap>
</abapGit>

View File

@@ -0,0 +1,48 @@
CLASS zcl_itab_combination DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES: BEGIN OF alphatab_type,
cola TYPE string,
colb TYPE string,
colc TYPE string,
END OF alphatab_type.
TYPES alphas TYPE STANDARD TABLE OF alphatab_type.
TYPES: BEGIN OF numtab_type,
col1 TYPE string,
col2 TYPE string,
col3 TYPE string,
END OF numtab_type.
TYPES nums TYPE STANDARD TABLE OF numtab_type.
TYPES: BEGIN OF combined_data_type,
colx TYPE string,
coly TYPE string,
colz TYPE string,
END OF combined_data_type.
TYPES combined_data TYPE STANDARD TABLE OF combined_data_type WITH EMPTY KEY.
METHODS perform_combination
IMPORTING
alphas TYPE alphas
nums TYPE nums
RETURNING
VALUE(combined_data) TYPE combined_data.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_itab_combination IMPLEMENTATION.
METHOD perform_combination.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,52 @@
CLASS ltcl_itab_combination DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL.
PRIVATE SECTION.
DATA cut TYPE REF TO zcl_itab_combination.
METHODS setup.
METHODS test_empty_input FOR TESTING RAISING cx_static_check.
METHODS test_single_row FOR TESTING RAISING cx_static_check.
METHODS test_combination FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltcl_itab_combination IMPLEMENTATION.
METHOD setup.
cut = NEW zcl_itab_combination( ).
ENDMETHOD.
METHOD test_empty_input.
cl_abap_unit_assert=>assert_equals(
act = cut->perform_combination( alphas = VALUE #( )
nums = VALUE #( ) )
exp = VALUE zcl_itab_combination=>combined_data( ) ).
ENDMETHOD.
METHOD test_single_row.
cl_abap_unit_assert=>assert_equals(
act = cut->perform_combination(
alphas = VALUE #( ( cola = 'A' colb = 'B' colc = 'C' ) )
nums = VALUE #( ( col1 = '1' col2 = '2' col3 = '3' ) ) )
exp = VALUE zcl_itab_combination=>combined_data( ( colx = 'A1' coly = 'B2' colz = 'C3' ) ) ).
ENDMETHOD.
METHOD test_combination.
cl_abap_unit_assert=>assert_equals(
act = cut->perform_combination(
alphas = VALUE #( ( cola = 'A' colb = 'B' colc = 'C' )
( cola = 'D' colb = 'E' colc = 'F' )
( cola = 'G' colb = 'H' colc = 'I' )
)
nums = VALUE #( ( col1 = '1' col2 = '2' col3 = '3' )
( col1 = '4' col2 = '5' col3 = '6' )
( col1 = '7' col2 = '8' col3 = '9' )
)
)
exp = VALUE zcl_itab_combination=>combined_data( ( colx = 'A1' coly = 'B2' colz = 'C3' )
( colx = 'D4' coly = 'E5' colz = 'F6' )
( colx = 'G7' coly = 'H8' colz = 'I9' )
) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOCLASS>
<CLSNAME>ZCL_ITAB_COMBINATION</CLSNAME>
<LANGU>E</LANGU>
<DESCRIPT>Exercism: Interal Table Combination</DESCRIPT>
<STATE>1</STATE>
<CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT>
<UNICODE>X</UNICODE>
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>

View File

@@ -0,0 +1,82 @@
# Instructions
Learn how to combine data from three different internal tables into one result internal table while nesting the associated data..
Your class will be given three internal tables which contain three completely different datasets, ARTISTS, ALBUMS, and SONGS.
```abap
TYPES: BEGIN OF artists_type,
artist_id TYPE string,
artist_name TYPE string,
END OF artists_type.
TYPES: artists TYPE STANDARD TABLE OF artists_type WITH KEY artist_id.
TYPES: BEGIN OF albums_type,
artist_id TYPE string,
album_id TYPE string,
album_name TYPE string,
END OF albums_type.
TYPES: albums TYPE STANDARD TABLE OF albums_type WITH KEY artist_id album_id.
TYPES: BEGIN OF songs_type,
artist_id TYPE string,
album_id TYPE string,
song_id TYPE string,
song_name TYPE string,
END OF songs_type.
TYPES: songs TYPE STANDARD TABLE OF songs_type WITH KEY artist_id album_id song_id.
```
The data in the ARTISTS table is as shown below.
| ARTIST_ID | ARTIST_NAME |
| --- | --- |
| 1 | Godsmack |
| 2 | Shinedown |
The data in the ALBUMS table is as shown below.
| ARTIST_ID | ALBUM_ID | ALBUM_NAME |
| --- | --- | --- |
| 1 | 1 | Faceless |
| 1 | 2 | When Lengends Rise |
| 2 | 1 | The Sound of Madness |
| 2 | 2 | Planet Zero |
The data in the SONGS table is as shown below.
| ARTIST_ID | ALBUM_ID | SONG_ID | SONG_NAME |
| --- | --- | --- | --- |
| 1 | 1 | 1 | Straight Out Of Line |
| 1 | 1 | 2 | Changes |
| 1 | 2 | 1 | Bullet Proof |
| 1 | 2 | 2 | Under Your Scars |
| 2 | 1 | 1 | Second Chance |
| 2 | 1 | 2 | Breaking Inside |
| 2 | 2 | 1 | Dysfunctional You |
| 2 | 2 | 2 | Daylight |
Your task is to return an internal table with records which combine the values of each internal table in a structured way, nesting the SONGS internal table into the ALBUMS internal table and of course nesting the ALBUMS internal table into the ARTISTS internal table.
The expected return table has the following definition:
```abap
TYPES: BEGIN OF song_nested_type,
song_id TYPE string,
song_name TYPE string,
END OF song_nested_type.
TYPES: BEGIN OF album_song_nested_type,
album_id TYPE string,
album_name TYPE string,
songs TYPE STANDARD TABLE OF song_nested_type WITH KEY song_Id,
END OF album_song_nested_type.
TYPES: BEGIN OF artist_album_nested_type,
artist_id TYPE string,
artist_name TYPE string,
albums TYPE STANDARD TABLE OF album_song_nested_type WITH KEY album_id,
END OF artist_album_nested_type.
TYPES: nested_data TYPE STANDARD TABLE OF artist_album_nested_type WITH KEY artist_id.
```
## Bonus
There are many ways to accomplish this task in ABAP. How efficiently can you complete the task?

View File

@@ -0,0 +1,13 @@
{
"blurb": "Given three different internal tables, combine the data from each table into one internal table while using nested tables",
"authors": ["rich-heilman"],
"contributors": [
],
"files": {
"solution": ["zcl_itab_nesting.clas.abap"],
"test": ["zcl_itab_nesting.clas.testclasses.abap"],
"example": [".meta/zcl_itab_nesting.clas.abap"]
},
"source": "ABAP Internal Tables",
"source_url": "https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenitab.htm"
}

View File

@@ -0,0 +1,90 @@
CLASS zcl_itab_nesting DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES: BEGIN OF artists_type,
artist_id TYPE string,
artist_name TYPE string,
END OF artists_type.
TYPES artists TYPE STANDARD TABLE OF artists_type WITH KEY artist_id.
TYPES: BEGIN OF albums_type,
artist_id TYPE string,
album_id TYPE string,
album_name TYPE string,
END OF albums_type.
TYPES albums TYPE STANDARD TABLE OF albums_type WITH KEY artist_id album_id.
TYPES: BEGIN OF songs_type,
artist_id TYPE string,
album_id TYPE string,
song_id TYPE string,
song_name TYPE string,
END OF songs_type.
TYPES songs TYPE STANDARD TABLE OF songs_type WITH KEY artist_id album_id song_id.
TYPES: BEGIN OF song_nested_type,
song_id TYPE string,
song_name TYPE string,
END OF song_nested_type.
TYPES: BEGIN OF album_song_nested_type,
album_id TYPE string,
album_name TYPE string,
songs TYPE STANDARD TABLE OF song_nested_type WITH KEY song_id,
END OF album_song_nested_type.
TYPES: BEGIN OF artist_album_nested_type,
artist_id TYPE string,
artist_name TYPE string,
albums TYPE STANDARD TABLE OF album_song_nested_type WITH KEY album_id,
END OF artist_album_nested_type.
TYPES nested_data TYPE STANDARD TABLE OF artist_album_nested_type WITH KEY artist_id.
METHODS perform_nesting
IMPORTING
artists TYPE artists
albums TYPE albums
songs TYPE songs
RETURNING
VALUE(nested_data) TYPE nested_data.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_itab_nesting IMPLEMENTATION.
METHOD perform_nesting.
LOOP AT artists REFERENCE INTO DATA(artist).
APPEND INITIAL LINE TO nested_data REFERENCE INTO DATA(nested_lvl1).
nested_lvl1->artist_id = artist->artist_id.
nested_lvl1->artist_name = artist->artist_name.
LOOP AT albums REFERENCE INTO DATA(album)
WHERE artist_id = artist->artist_id.
APPEND INITIAL LINE TO nested_lvl1->albums REFERENCE INTO DATA(nested_lvl2).
nested_lvl2->album_id = album->album_id.
nested_lvl2->album_name = album->album_name.
LOOP AT songs REFERENCE INTO DATA(song)
WHERE artist_id = album->artist_id
AND album_id = album->album_id.
APPEND INITIAL LINE TO nested_lvl2->songs REFERENCE INTO DATA(nested_lvl3).
nested_lvl3->song_id = song->song_id.
nested_lvl3->song_name = song->song_name.
ENDLOOP.
ENDLOOP.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DEVC" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DEVC>
<CTEXT>Exercism: Interal Table Nesting</CTEXT>
</DEVC>
</asx:values>
</asx:abap>
</abapGit>

View File

@@ -0,0 +1,62 @@
CLASS zcl_itab_nesting DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES: BEGIN OF artists_type,
artist_id TYPE string,
artist_name TYPE string,
END OF artists_type.
TYPES artists TYPE STANDARD TABLE OF artists_type WITH KEY artist_id.
TYPES: BEGIN OF albums_type,
artist_id TYPE string,
album_id TYPE string,
album_name TYPE string,
END OF albums_type.
TYPES albums TYPE STANDARD TABLE OF albums_type WITH KEY artist_id album_id.
TYPES: BEGIN OF songs_type,
artist_id TYPE string,
album_id TYPE string,
song_id TYPE string,
song_name TYPE string,
END OF songs_type.
TYPES songs TYPE STANDARD TABLE OF songs_type WITH KEY artist_id album_id song_id.
TYPES: BEGIN OF song_nested_type,
song_id TYPE string,
song_name TYPE string,
END OF song_nested_type.
TYPES: BEGIN OF album_song_nested_type,
album_id TYPE string,
album_name TYPE string,
songs TYPE STANDARD TABLE OF song_nested_type WITH KEY song_id,
END OF album_song_nested_type.
TYPES: BEGIN OF artist_album_nested_type,
artist_id TYPE string,
artist_name TYPE string,
albums TYPE STANDARD TABLE OF album_song_nested_type WITH KEY album_id,
END OF artist_album_nested_type.
TYPES nested_data TYPE STANDARD TABLE OF artist_album_nested_type WITH KEY artist_id.
METHODS perform_nesting
IMPORTING
artists TYPE artists
albums TYPE albums
songs TYPE songs
RETURNING
VALUE(nested_data) TYPE nested_data.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_itab_nesting IMPLEMENTATION.
METHOD perform_nesting.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,94 @@
CLASS ltcl_itab_nesting DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL.
PRIVATE SECTION.
DATA cut TYPE REF TO zcl_itab_nesting.
METHODS setup.
METHODS test_empty_input FOR TESTING RAISING cx_static_check.
METHODS test_single_artist FOR TESTING RAISING cx_static_check.
METHODS test_single_artist_no_album FOR TESTING RAISING cx_static_check.
METHODS test_nesting FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltcl_itab_nesting IMPLEMENTATION.
METHOD setup.
cut = NEW zcl_itab_nesting( ).
ENDMETHOD.
METHOD test_empty_input.
cl_abap_unit_assert=>assert_equals(
act = cut->perform_nesting( artists = VALUE #( )
albums = VALUE #( )
songs = VALUE #( ) )
exp = VALUE zcl_itab_nesting=>nested_data( ) ).
ENDMETHOD.
METHOD test_single_artist.
cl_abap_unit_assert=>assert_equals(
act = cut->perform_nesting(
artists = VALUE #( ( artist_id = '1' artist_name = 'Godsmack' ) )
albums = VALUE #( ( artist_id = '1' album_id = '1' album_name = 'Faceless' ) )
songs = VALUE #( ( artist_id = '1' album_id = '1' song_id = '1' song_name = 'Straight Out Of Line' ) ) )
exp = VALUE zcl_itab_nesting=>nested_data( ( artist_id = '1' artist_name = 'Godsmack'
albums = VALUE #( ( album_id = '1' album_name = 'Faceless'
songs = VALUE #( ( song_id = '1' song_name = 'Straight Out Of Line' ) )
) )
) ) ).
ENDMETHOD.
METHOD test_single_artist_no_album.
cl_abap_unit_assert=>assert_equals(
act = cut->perform_nesting(
artists = VALUE #( ( artist_id = '1' artist_name = 'Godsmack' ) )
albums = VALUE #( )
songs = VALUE #( ) )
exp = VALUE zcl_itab_nesting=>nested_data( ( artist_id = '1' artist_name = 'Godsmack'
albums = VALUE #( ) ) ) ).
ENDMETHOD.
METHOD test_nesting.
cl_abap_unit_assert=>assert_equals(
act = cut->perform_nesting(
artists = VALUE #( ( artist_id = '1' artist_name = 'Godsmack' )
( artist_id = '2' artist_name = 'Shinedown' ) )
albums = VALUE #( ( artist_id = '1' album_id = '1' album_name = 'Faceless' )
( artist_id = '1' album_id = '2' album_name = 'When Lengends Rise' )
( artist_id = '2' album_id = '1' album_name = 'The Sound of Madness' )
( artist_id = '2' album_id = '2' album_name = 'Planet Zero' )
)
songs = VALUE #( ( artist_id = '1' album_id = '1' song_id = '1' song_name = 'Straight Out Of Line' )
( artist_id = '1' album_id = '1' song_id = '2' song_name = 'Changes' )
( artist_id = '1' album_id = '2' song_id = '1' song_name = 'Bullet Proof' )
( artist_id = '1' album_id = '2' song_id = '2' song_name = 'Under Your Scars' )
( artist_id = '2' album_id = '1' song_id = '1' song_name = 'Second Chance' )
( artist_id = '2' album_id = '1' song_id = '2' song_name = 'Breaking Inside' )
( artist_id = '2' album_id = '2' song_id = '1' song_name = 'Dysfunctional You' )
( artist_id = '2' album_id = '2' song_id = '2' song_name = 'Daylight' )
)
)
exp = VALUE zcl_itab_nesting=>nested_data(
( artist_id = '1' artist_name = 'Godsmack'
albums = VALUE #( ( album_id = '1' album_name = 'Faceless'
songs = VALUE #( ( song_id = '1' song_name = 'Straight Out Of Line' )
( song_id = '2' song_name = 'Changes' )
) )
( album_id = '2' album_name = 'When Lengends Rise'
songs = VALUE #( ( song_id = '1' song_name = 'Bullet Proof' )
( song_id = '2' song_name = 'Under Your Scars' )
) )
) )
( artist_id = '2' artist_name = 'Shinedown'
albums = VALUE #( ( album_id = '1' album_name = 'The Sound of Madness'
songs = VALUE #( ( song_id = '1' song_name = 'Second Chance' )
( song_id = '2' song_name = 'Breaking Inside' )
) )
( album_id = '2' album_name = 'Planet Zero'
songs = VALUE #( ( song_id = '1' song_name = 'Dysfunctional You' )
( song_id = '2' song_name = 'Daylight' )
) )
) )
) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOCLASS>
<CLSNAME>ZCL_ITAB_NESTING</CLSNAME>
<LANGU>E</LANGU>
<DESCRIPT>Exercism: Interal Table Nesting</DESCRIPT>
<STATE>1</STATE>
<CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT>
<UNICODE>X</UNICODE>
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>