[FREE] ListNinja Extension from Still_Learning

🧩 ListNinja

An extension for MIT App Inventor 2.
ListNinja: Powerful List Utilities Extension by Jaisankar - Supports Yail & JSON lists

:memo: Specifications


:package: Package: io.jsr.listninja.listninja
:floppy_disk: Size: 37.49 KB
:mobile_phone: Minimum API Level: 7
:date: Updated On: 2025-06-20T18:30:00Z
:laptop: Built & documented using: FAST v3.7.0

Special thanks to @JEWEL for his wonderful platform FAST CLi

Version 7 with almost 50 functions is updated using FAST CLi Extension builder

The ListNinja extension provides advanced list manipulation for App Inventor, supporting 1D, 2D, and 3D lists.

The following functions have been updated to include a dropdown for conditions using the Condition enum, which implements OptionList<String>. This creates a user-friendly dropdown menu in App Inventor for selecting conditions like equals, not_equals, etc., ensuring valid inputs. Examples use a sample list: [["Fighting, Anime", "1"], ["Action, Adventure", "10"], ["Racing", "2"], ["Action, Flight", "116"]].

Condition Enum (OptionList)

Summary

Credit to @Taifun for his solution

The Condition enum provides a dropdown for the condition parameter in FilterByCondition, PartitionList, and ReplaceByCondition. It includes:

  • equals, not_equals, greater, less, greater_or_equal, less_or_equal
  • contains, starts_with, ends_with
  • is_empty, not_empty
  • contains_element, length_equals, length_greater, length_less

Benefit: The dropdown prevents invalid condition inputs, making blocks easier to configure. For example, selecting equals ensures numeric comparisons for DATA (index 2) like "10" are treated as numbers (10).

FilterByCondition

Filters a list based on a condition applied to elements or a specified index in sublists. Supports 1D, 2D, and 3D lists.

Parameters

  • list (YailList): Input list (e.g., [["Fighting, Anime", "1"], ["Racing", "2"]]) or 1D list (e.g., ["1", "2"]).
  • index (int): 1-based index to check in sublists (e.g., 2 for DATA). Use 0 for 1D lists or conditions like length_equals.
  • condition (String): Selected from a dropdown (via OptionList):
    • Numeric: equals, not_equals, greater, less, greater_or_equal, less_or_equal
    • String: contains, starts_with, ends_with, is_empty, not_empty
    • List: contains_element, length_equals, length_greater, length_less
  • value (Object): Value to compare (e.g., "10" or 10).
  • caseSensitive (boolean): True for case-sensitive string comparisons, false otherwise.

Returns

  • YailList: Filtered list of matching elements or sublists.

Example

Goal: Filter sublists where DATA (index 2) equals "10".

  • Input List: [["Fighting, Anime", "1"], ["Action, Adventure", "10"], ["Racing", "2"], ["Action, Flight", "116"]]
  • Blocks:
    • Use ListNinja.FilterByCondition.
    • Set list to the input list.
    • Set index to 2.
    • Select condition as equals from the dropdown.
    • Set value to "10".
    • Set caseSensitive to false.
  • Output: [["Action, Adventure", "10"]]

Notes:

  • Numeric strings (e.g., "10") are compared numerically for equals, greater, etc.
  • Use index = 0 for length_equals, contains_element.

PartitionList

Partitions a list into two lists: one matching a condition and one not matching. Returns [matching, non-matching].

Parameters

  • list (YailList): Input list (e.g., [["Fighting, Anime", "1"], ["Racing", "2"]]).
  • index (int): 1-based index to check (e.g., 1 for Genre). Use 0 for 1D lists or list-based conditions.
  • condition (String): Selected from the Condition dropdown (see above).
  • value (Object): Value to compare (e.g., "Action").
  • caseSensitive (boolean): True for case-sensitive string comparisons.

Returns

  • YailList: List containing two sublists: [matching, non-matching].

Example

Goal: Partition sublists where Genre (index 1) contains "Action".

  • Input List: [["Fighting, Anime", "1"], ["Action, Adventure", "10"], ["Racing", "2"], ["Action, Flight", "116"]]
  • Blocks:
    • Use ListNinja.PartitionList.
    • Set list to the input list.
    • Set index to 1.
    • Select condition as contains from the dropdown.
    • Set value to "Action".
    • Set caseSensitive to false.
  • Output: [[["Action, Adventure", "10"], ["Action, Flight", "116"]], [["Fighting, Anime", "1"], ["Racing", "2"]]]

Notes:

  • The dropdown ensures valid conditions.
  • Numeric comparisons apply for DATA (index 2) when using equals, greater, etc.

ReplaceByCondition

Replaces elements or sublists matching a condition with a new value.

Parameters

  • list (YailList): Input list (e.g., [["Fighting, Anime", "1"], ["Racing", "2"]]).
  • index (int): 1-based index to check (e.g., 2 for DATA). Use 0 for 1D lists or list-based conditions.
  • condition (String): Selected from the Condition dropdown (see above).
  • value (Object): Value to compare (e.g., "1").
  • replacement (Object): Replacement value (e.g., "100").
  • caseSensitive (boolean): True for case-sensitive string comparisons.

Returns

  • YailList: List with matching elements or sublists replaced.

Example

Goal: Replace DATA (index 2) values equaling "1" with "100".

  • Input List: [["Fighting, Anime", "1"], ["Action, Adventure", "10"], ["Racing", "2"]]
  • Blocks:
    • Use ListNinja.ReplaceByCondition.
    • Set list to the input list.
    • Set index to 2.
    • Select condition as equals from the dropdown.
    • Set value to "1".
    • Set replacement to "100".
    • Set caseSensitive to false.
  • Output: [["Fighting, Anime", "100"], ["Action, Adventure", "10"], ["Racing", "2"]]

Notes:

  • Numeric strings are compared numerically for equals.
  • For list-based conditions, the entire sublist is replaced.

SortByMultipleIndices

Sorts a list of lists by multiple indices in order.

Parameters

  • listOfLists (YailList): List of sublists (e.g., [["Fighting, Anime", "1"], ["Racing", "2"]]).
  • indices (YailList): 1-based indices to sort by (e.g., [2] for DATA).
  • ascending (boolean): True for ascending, false for descending.

Returns

  • YailList: Sorted list of sublists.

Example

Goal: Sort by DATA (index 2) in ascending order.

  • Input List: [["Action, Flight", "116"], ["Fighting, Anime", "1"], ["Action, Adventure", "10"]]
  • Blocks:
    • Use ListNinja.SortByMultipleIndices.
    • Set listOfLists to the input list.
    • Set indices to [2].
    • Set ascending to true.
  • Output: [["Fighting, Anime", "1"], ["Action, Adventure", "10"], ["Action, Flight", "116"]]

Notes:

  • Numeric strings (e.g., "116") are sorted numerically.
  • Multiple indices sort sequentially (e.g., [2, 1] sorts by DATA, then Genre).

AggregateByIndex

Aggregates numeric values at a specified index, optionally grouped by another index. Operations: sum, average, min, max, count.

Parameters

  • listOfLists (YailList): List of sublists (e.g., [["Fighting, Anime", "1"], ["Racing", "2"]]).
  • valueIndex (int): 1-based index of numeric values (e.g., 2 for DATA).
  • operation (String): Aggregation type (sum, average, min, max, count).
  • groupByIndex (int): 1-based index to group by (e.g., 1 for Genre). Use 0 for no grouping.

Returns

  • YailList: List of [groupKey, result] pairs.

Example

Goal: Sum DATA (index 2) grouped by Genre (index 1).

  • Input List: [["Action, Anime", "1"], ["Action, Adventure", "10"], ["Action, Anime", "2"]]
  • Blocks:
    • Use ListNinja.AggregateByIndex.
    • Set listOfLists to the input list.
    • Set valueIndex to 2.
    • Set operation to "sum".
    • Set groupByIndex to 1.
  • Output: [["Action, Anime", 3.0], ["Action, Adventure", 10.0]]

Notes:

  • Non-numeric values at valueIndex trigger an error.
  • Use groupByIndex = 0 for a single aggregate result.

(Extension updated in the first post)

1 Like