cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Choose Language Hide Translation Bar
miguello
Level VI

How to iterate over list of associative arrays grouped by a specific key values?

Let's say I have a list of associative arrays.

I want to iterate over this list by groups. First by category, then, in a nested loop, by subcategory.

aalist = {
	[
		"Category" => "A",
		"Subcategory" => "aa",
		"Value" => "123"
	]
	,
	[
		"Category" => "A",
		"Subcategory" => "aa",
		"Value" => "124"
	]
	,
		[
		"Category" => "A",
		"Subcategory" => "bb",
		"Value" => "125"
	]
	,
		[
		"Category" => "A",
		"Subcategory" => "bb",
		"Value" => "124"
	]
	,
		[
		"Category" => "A",
		"Subcategory" => "cc",
		"Value" => "125"
	]
	,
	
		[
		"Category" => "B",
		"Subcategory" => "aa",
		"Value" => "126"
	]
	,
		[
		"Category" => "B",
		"Subcategory" => "aa",
		"Value" => "127"
	]
	,
	[
		"Category" => "B",
		"Subcategory" => "bb",
		"Value" => "127"
	]
	,	
			[
		"Category" => "B",
		"Subcategory" => "bb",
		"Value" => "126"
	]
	,
		[
		"Category" => "B",
		"Subcategory" => "cc",
		"Value" => "127"
	]
	,
	[
		"Category" => "B",
		"Subcategory" => "cc",
		"Value" => "127"
	]
	,	
			[
		"Category" => "B",
		"Subcategory" => "cc",
		"Value" => "126"
	]
};

Meaning that in my first loop on the first iteration I get a list of associative arrays where Category is "A". In the nested loop I iterate through subcategories, where on first iteration I get a list of all associative arrays with Subcategory "aa", and so on.

A good example of what I need to accomplish can be shown in PowerShell as follows:

# Sample data
$data = @(
    [PSCustomObject]@{ Name = "Alice";  Group = "A" }
    [PSCustomObject]@{ Name = "Bob";    Group = "B" }
    [PSCustomObject]@{ Name = "Charlie"; Group = "A" }
    [PSCustomObject]@{ Name = "David";  Group = "B" }
)

# Group the data by the 'Group' property
$groupedData = $data | Group-Object -Property Group

# Iterate over each group
foreach ($group in $groupedData) {
    Write-Host "Group: $($group.Name)"

    # Iterate over each item within the group
    foreach ($item in $group.Group) {
        Write-Host "  Name: $($item.Name)"
    }
}

How do I do something like that in JSL?

1 ACCEPTED SOLUTION

Accepted Solutions
miguello
Level VI

Re: How to iterate over list of associative arrays grouped by a specific key values?

Ok, here is how I did it in JSL:

aalist = {
	[
		"Category" => "A",
		"Subcategory" => "aa",
		"Value" => "123"
	]
	,
	[
		"Category" => "A",
		"Subcategory" => "aa",
		"Value" => "124"
	]
	,
		[
		"Category" => "A",
		"Subcategory" => "bb",
		"Value" => "125"
	]
	,
		[
		"Category" => "A",
		"Subcategory" => "bb",
		"Value" => "124"
	]
	,
		[
		"Category" => "A",
		"Subcategory" => "cc",
		"Value" => "125"
	]
	,
	
		[
		"Category" => "B",
		"Subcategory" => "aa",
		"Value" => "126"
	]
	,
		[
		"Category" => "B",
		"Subcategory" => "aa",
		"Value" => "127"
	]
	,
	[
		"Category" => "B",
		"Subcategory" => "bb",
		"Value" => "127"
	]
	,	
			[
		"Category" => "B",
		"Subcategory" => "bb",
		"Value" => "126"
	]
	,
		[
		"Category" => "B",
		"Subcategory" => "cc",
		"Value" => "127"
	]
	,
	[
		"Category" => "B",
		"Subcategory" => "cc",
		"Value" => "127"
	]
	,	
			[
		"Category" => "B",
		"Subcategory" => "cc",
		"Value" => "126"
	]
};

// Function to group by a property
groupBy = Function( {list, property},
    {Default local},
    groups = Associative Array();
   For Each({item, index}, list,
        key = item[property];
        If( !Contains( groups, key ),
            groups[key] = {};
        );
        Insert Into( groups[key], item );
    );
    groups;
);

// Group the list by the "Department" property
grouped = groupBy(aalist, "Category");

// Iterate over the groups
For Each( {{key, value}, index}, grouped,
    Write("\!nCategory: " || key);
    subgrouped = groupBy(value, "Subcategory");
	For Each( {{key, value}, index}, subgrouped,
		Write("\!n     - Subcategory: "|| key);
		For Each({item, index}, value,
			Write("\!n               - Category: "||item["Category"]||", Subcategory: "||item["Subcategory"]||", Value = "||Char(item["Value"]))
		)	
	);
    
);

Output:

Category: A
     - Subcategory: aa
               - Category: A, Subcategory: aa, Value = 123
               - Category: A, Subcategory: aa, Value = 124
     - Subcategory: bb
               - Category: A, Subcategory: bb, Value = 125
               - Category: A, Subcategory: bb, Value = 124
     - Subcategory: cc
               - Category: A, Subcategory: cc, Value = 125
Category: B
     - Subcategory: aa
               - Category: B, Subcategory: aa, Value = 126
               - Category: B, Subcategory: aa, Value = 127
     - Subcategory: bb
               - Category: B, Subcategory: bb, Value = 127
               - Category: B, Subcategory: bb, Value = 126
     - Subcategory: cc
               - Category: B, Subcategory: cc, Value = 127
               - Category: B, Subcategory: cc, Value = 127
               - Category: B, Subcategory: cc, Value = 126

View solution in original post

2 REPLIES 2
miguello
Level VI

Re: How to iterate over list of associative arrays grouped by a specific key values?

Ok, here is how I did it in JSL:

aalist = {
	[
		"Category" => "A",
		"Subcategory" => "aa",
		"Value" => "123"
	]
	,
	[
		"Category" => "A",
		"Subcategory" => "aa",
		"Value" => "124"
	]
	,
		[
		"Category" => "A",
		"Subcategory" => "bb",
		"Value" => "125"
	]
	,
		[
		"Category" => "A",
		"Subcategory" => "bb",
		"Value" => "124"
	]
	,
		[
		"Category" => "A",
		"Subcategory" => "cc",
		"Value" => "125"
	]
	,
	
		[
		"Category" => "B",
		"Subcategory" => "aa",
		"Value" => "126"
	]
	,
		[
		"Category" => "B",
		"Subcategory" => "aa",
		"Value" => "127"
	]
	,
	[
		"Category" => "B",
		"Subcategory" => "bb",
		"Value" => "127"
	]
	,	
			[
		"Category" => "B",
		"Subcategory" => "bb",
		"Value" => "126"
	]
	,
		[
		"Category" => "B",
		"Subcategory" => "cc",
		"Value" => "127"
	]
	,
	[
		"Category" => "B",
		"Subcategory" => "cc",
		"Value" => "127"
	]
	,	
			[
		"Category" => "B",
		"Subcategory" => "cc",
		"Value" => "126"
	]
};

// Function to group by a property
groupBy = Function( {list, property},
    {Default local},
    groups = Associative Array();
   For Each({item, index}, list,
        key = item[property];
        If( !Contains( groups, key ),
            groups[key] = {};
        );
        Insert Into( groups[key], item );
    );
    groups;
);

// Group the list by the "Department" property
grouped = groupBy(aalist, "Category");

// Iterate over the groups
For Each( {{key, value}, index}, grouped,
    Write("\!nCategory: " || key);
    subgrouped = groupBy(value, "Subcategory");
	For Each( {{key, value}, index}, subgrouped,
		Write("\!n     - Subcategory: "|| key);
		For Each({item, index}, value,
			Write("\!n               - Category: "||item["Category"]||", Subcategory: "||item["Subcategory"]||", Value = "||Char(item["Value"]))
		)	
	);
    
);

Output:

Category: A
     - Subcategory: aa
               - Category: A, Subcategory: aa, Value = 123
               - Category: A, Subcategory: aa, Value = 124
     - Subcategory: bb
               - Category: A, Subcategory: bb, Value = 125
               - Category: A, Subcategory: bb, Value = 124
     - Subcategory: cc
               - Category: A, Subcategory: cc, Value = 125
Category: B
     - Subcategory: aa
               - Category: B, Subcategory: aa, Value = 126
               - Category: B, Subcategory: aa, Value = 127
     - Subcategory: bb
               - Category: B, Subcategory: bb, Value = 127
               - Category: B, Subcategory: bb, Value = 126
     - Subcategory: cc
               - Category: B, Subcategory: cc, Value = 127
               - Category: B, Subcategory: cc, Value = 127
               - Category: B, Subcategory: cc, Value = 126
jthi
Super User

Re: How to iterate over list of associative arrays grouped by a specific key values?

Same idea, rebuild your list into something more usable and then do whatever you need with it

Names Default To Here(1);

aalist = {["Category" => "A", "Subcategory" => "aa", "Value" => "123"], ["Category" => "A", "Subcategory" => "aa",
"Value" => "124"], ["Category" => "A", "Subcategory" => "bb", "Value" => "125"], ["Category" => "A", "Subcategory"
 => "bb", "Value" => "124"], ["Category" => "A", "Subcategory" => "cc", "Value" => "125"], ["Category" => "B",
"Subcategory" => "aa", "Value" => "126"], ["Category" => "B", "Subcategory" => "aa", "Value" => "127"], ["Category"
 => "B", "Subcategory" => "bb", "Value" => "127"], ["Category" => "B", "Subcategory" => "bb", "Value" => "126"], [
"Category" => "B", "Subcategory" => "cc", "Value" => "127"], ["Category" => "B", "Subcategory" => "cc", "Value" =>
"127"], ["Category" => "B", "Subcategory" => "cc", "Value" => "126"]};
 
aa = Associative Array();

For Each({aa_item}, aalist,
	If(!Contains(aa, aa_item["Category"]),
		aa[aa_item["Category"]] = Associative Array();
	);
	If(!Contains(aa[aa_item["Category"]], aa_item["Subcategory"]),
		aa[aa_item["Category"]][aa_item["Subcategory"]] = {};
	);
	Insert Into(aa[aa_item["Category"]][aa_item["Subcategory"]], aa_item["Value"]);
);

For Each({{category, subcategory}}, aa,
	Write("\!NCategory: ", category);
	For Each({{subcategory_key, subcategory_values}}, subcategory,
		Write("\!N\!t- Subcategory: ", subcategory_key);
		For Each({value}, subcategory_values,
			Write("\!N\!t\!t- Category: ", category, ", Subcategory: ", subcategory_key, ", Value = ", value);
		);
	);
);
-Jarmo