Skip to content

Instantly share code, notes, and snippets.

@steveosoule
Last active May 21, 2020 18:26
Show Gist options
  • Save steveosoule/c3de3a49ed4bffb6b75d8f4cf0a79809 to your computer and use it in GitHub Desktop.
Save steveosoule/c3de3a49ed4bffb6b75d8f4cf0a79809 to your computer and use it in GitHub Desktop.
Miva - Array Opperations

Miva Array Opperations

The following are a couple examples of some common array opperations done in the Miva Template Language.

They include a couple example problems and illustrate some different ways of providing a solution in MVT.

There are also JavaScript examples of the same problems & solutions to help bridge the MVT concepts for people that are more familiar with JavaScript.

Table of Contents

  • Sample Data
  • Does the outfit list have a T-Shirt in it?
    • mvt:foreach
    • miva_array_search
    • js
      • for
      • Array.forEach
      • Array.some
  • Which items in the outfit are blue?
    • mvt:foreach
    • miva_array_filter
    • js
      • for
      • Array.forEach
      • Array.filter
  • Sum up the prices & quantities for each color of item in the outfit.
    • mvt:foreach
    • miva_array_filter_ref
    • js
      • for
      • Array.forEach
      • Array.reduce

Sample Data

Sample Data > Miva Template Languange

<mvt:capture variable="l.outfit_products_json">
[
	{
		"name": "Hat",
		"color": "Black",
		"price": 19.99
	},
	{
		"name": "T-Shirt",
		"color": "Blue",
		"price": 14.99
	},
	{
		"name": "T-Shirt",
		"color": "Blue",
		"price": 15.99
	},
	{
		"name": "Pants",
		"color": "Blue",
		"price": 39.99
	},
	{
		"name": "Socks",
		"color": "Black",
		"price": 5.99
	},
	{
		"name": "Socks",
		"color": "Black",
		"price": 5.99
	},
	{
		"name": "Shoes",
		"color": "Black",
		"price": 39.99
	}
]
</mvt:capture>
<mvt:assign name="l.result" value="miva_json_decode( l.outfit_products_json, l.settings:outfit_products )" />

Sample Data > JavaScript

var outfit_products = [
	{
		name: "Hat",
		color: "Black",
		price: 19.99
	},
	{
		name: "T-Shirt",
		color: "Blue",
		price: 14.99
	},
	{
		name: "T-Shirt",
		color: "Blue",
		price: 15.99
	},
	{
		name: "Pants",
		color: "Blue",
		price: 39.99
	},
	{
		name: "Socks",
		color: "Black",
		price: 5.99
	},
	{
		name: "Socks",
		color: "Black",
		price: 5.99
	},
	{
		name: "Shoes",
		color: "Black",
		price: 39.99
	}
];

Does the outfit list have a T-Shirt in it?

Does the outfit list have a T-Shirt in it? - mvt:foreach

<mvt:assign name="l.found_shirt" value="0" />
<mvt:foreach iterator="product" array="outfit_products">
	<mvt:if expr="l.settings:product:name EQ 'T-Shirt'">
		<mvt:assign name="l.found_shirt" value="1" />
		<mvt:foreachstop />
	</mvt:if>
</mvt:foreach>

Does the outfit list have a T-Shirt in it? - miva_array_search

<mvt:assign name="l.found_shirt" value="miva_array_search( l.settings:outfit_products, 0, l.product, 'l.product:name EQ \'T-Shirt\'' ) GT 0" />

Does the outfit list have a T-Shirt in it? - JavaScript: for

var found_shirt = false;
for (var i = 0, len = outfit_products.length; i < len; i++) {
	var product = outfit_products[i];

	if( product.name === 'T-Shirt' ) {
		found_shirt = true;
		break;
	}
}

Does the outfit list have a T-Shirt in it? - JavaScript: Array.forEach

var found_shirt = false;
outfit_products.forEach(function(product){
	if( product.name === 'T-Shirt' ) {
		found_shirt = true;
	}
});

Does the outfit list have a T-Shirt in it? - JavaScript: Array.some

var found_shirt = outfit_products.some(function(product){
	return product.name === 'T-Shirt';
});

Which items in the outfit are blue?

Which items in the outfit are blue? - mvt:foreach

<mvt:foreach iterator="product" array="outfit_products">
	<mvt:if expr="l.settings:product:color EQ 'Blue'">
		<mvt:assign name="l.result" value="miva_array_insert( l.blue_products, l.settings:product, -1 )" />
	</mvt:if>
</mvt:foreach>

Which items in the outfit are blue? - miva_array_filter

<mvt:assign name="l.count" value="miva_array_filter( l.settings:outfit_products, 0, l.product, 'l.product:color EQ \'Blue\'', l.blue_products )" />

Which items in the outfit are blue? - JavaScript: for

var blue_products = [];
for (var i = 0, len = outfit_products.length; i < len; i++) {
	var product = outfit_products[i];

	if( product.color === 'Blue' ) {
		blue_products.push(product);
	}
}

Which items in the outfit are blue? - JavaScript: Array.forEach

var blue_products = [];
outfit_products.forEach(function(product){
	if( product.color === 'Blue' ) {
		blue_products.push(product);
	}
});

Which items in the outfit are blue? - JavaScript: Array.some

var blue_products = outfit_products.filter(function(product){
	return product.color === 'Blue';
});

Sum up the prices & quantities for each color of item in the outfit

Sum up the prices & quantities for each color of item in the outfit - mvt:foreach

<mvt:comment>It's not possible or recommended to even try this</mvt:comment>

Sum up the prices & quantities for each color of item in the outfit - miva_array_filter_ref

<mvt:foreach iterator="outfit_product" array="outfit_products">
	<mvt:assign name="l.existing_color_item_count" value="miva_array_filter_ref( l.color_items, 1, l.color_item, 'l.color_item:color EQ l.settings:outfit_product:color', l.existing_color_items )" />

	<mvt:if expr="l.existing_color_item_count">
		<mvt:assign name="l.existing_color_items[1]:total_quantity" value="l.existing_color_items[1]:total_quantity + 1" />
		<mvt:assign name="l.existing_color_items[1]:total_price" value="l.existing_color_items[1]:total_price + l.settings:outfit_product:price" />
	<mvt:else>
		<mvt:assign name="l.new_color_item" value="''" />
		<mvt:assign name="l.new_color_item:color" value="l.settings:outfit_product:color" />
		<mvt:assign name="l.new_color_item:total_quantity" value="1" />
		<mvt:assign name="l.new_color_item:total_price" value="l.settings:outfit_product:price" />
		
		<mvt:assign name="l.result" value="miva_array_insert( l.color_items, l.new_color_item, -1 )" />
	</mvt:if>

</mvt:foreach>

Sum up the prices & quantities for each color of item in the outfit - JavaScript: for

var totals = {};
for (var i = 0, len = outfit_products.length; i < len; i++) {
	var product = outfit_products[i];
	if( typeof totals[product.color] === 'object' ){
		totals[product.color].total_quantity++;
		totals[product.color].total_price += product.price;
	}
	else {
		totals[product.color] = {
			total_quantity: 1,
			total_price: product.price
		};
	}
}

Sum up the prices & quantities for each color of item in the outfit - JavaScript: Array.forEach

var totals = {};
outfit_products.forEach(function(product){
	if( typeof totals[product.color] === 'undefined' ){
		totals[product.color] = {
			total_quantity: 1,
			total_price: product.price
		};
	}
	else {
		totals[product.color].total_quantity++;
		totals[product.color].total_price += product.price;
	}
});

Sum up the prices & quantities for each color of item in the outfit - JavaScript: Array.reduce

var totals = outfit_products.reduce(function(accumulator_totals, product){
	if( typeof accumulator_totals[product.color] === 'object' ){
		accumulator_totals[product.color].total_quantity++;
		accumulator_totals[product.color].total_price += product.price;
	}
	else {
		accumulator_totals[product.color] = {
			total_quantity: 1,
			total_price: product.price
		};
	}
	return accumulator_totals
}, {});
<mvt:capture variable="l.outfit_products_json">
[
{
"name": "Hat",
"color": "Black",
"price": 19.99
},
{
"name": "T-Shirt",
"color": "Blue",
"price": 14.99
},
{
"name": "T-Shirt",
"color": "Blue",
"price": 15.99
},
{
"name": "Pants",
"color": "Blue",
"price": 39.99
},
{
"name": "Socks",
"color": "Black",
"price": 5.99
},
{
"name": "Socks",
"color": "Black",
"price": 5.99
},
{
"name": "Shoes",
"color": "Black",
"price": 39.99
}
]
</mvt:capture>
<mvt:assign name="l.result" value="miva_json_decode( l.outfit_products_json, l.settings:outfit_products )" />
<h2>Does the outfit list have a T-Shirt in it? - mvt:foreach</h2>
<mvt:assign name="l.found_shirt" value="0" />
<mvt:foreach iterator="product" array="outfit_products">
<mvt:if expr="l.settings:product:name EQ 'T-Shirt'">
<mvt:assign name="l.found_shirt" value="1" />
<mvt:foreachstop />
</mvt:if>
</mvt:foreach>
<p>l.found_shirt=<mvt:eval expr="l.found_shirt" /></p>
<p><i>Output: <pre>l.found_shirt=1</pre></i></p>
<h2>Does the outfit list have a T-Shirt in it? - miva_array_search</h2>
<mvt:assign name="l.found_shirt" value="miva_array_search( l.settings:outfit_products, 0, l.product, 'l.product:name EQ \'T-Shirt\'' ) GT 0" />
<p>l.found_shirt=<mvt:eval expr="l.found_shirt" /></p>
<p><i>Output: <pre>l.found_shirt=1</pre></i></p>
<h2>Which items in the outfit are blue? - mvt:foreach</h2>
<mvt:foreach iterator="product" array="outfit_products">
<mvt:if expr="l.settings:product:color EQ 'Blue'">
<mvt:assign name="l.result" value="miva_array_insert( l.blue_products, l.settings:product, -1 )" />
</mvt:if>
</mvt:foreach>
<mvt:assign name="g.mvt_debug" value="glosub( miva_array_serialize( l.blue_products ), ',', asciichar( 10 ) )" />
<pre>&mvt:global:mvt_debug;</pre>
<p><i>Output: <pre>[1]:color=Blue
[1]:name=T-Shirt
[1]:price=14.99
[2]:color=Blue
[2]:name=T-Shirt
[2]:price=15.99
[3]:color=Blue
[3]:name=Pants
[3]:price=39.99</pre></i></p>
<h2>Which items in the outfit are blue? - miva_array_filter</h2>
<mvt:assign name="l.count" value="miva_array_filter( l.settings:outfit_products, 0, l.product, 'l.product:color EQ \'Blue\'', l.blue_products )" />
<mvt:assign name="g.mvt_debug" value="glosub( miva_array_serialize( l.blue_products ), ',', asciichar( 10 ) )" />
<pre>&mvt:global:mvt_debug;</pre>
<p><i>Output: <pre>[1]:color=Blue
[1]:name=T-Shirt
[1]:price=14.99
[2]:color=Blue
[2]:name=T-Shirt
[2]:price=15.99
[3]:color=Blue
[3]:name=Pants
[3]:price=39.99</pre></i></p>
<h2>Sum up the prices & quantities for each color of item in the outfit - miva_array_filter_ref</h2>
<mvt:foreach iterator="outfit_product" array="outfit_products">
<mvt:assign name="l.existing_color_item_count" value="miva_array_filter_ref( l.color_items, 1, l.color_item, 'l.color_item:color EQ l.settings:outfit_product:color', l.existing_color_items )" />
<mvt:if expr="l.existing_color_item_count">
<mvt:assign name="l.existing_color_items[1]:total_quantity" value="l.existing_color_items[1]:total_quantity + 1" />
<mvt:assign name="l.existing_color_items[1]:total_price" value="l.existing_color_items[1]:total_price + l.settings:outfit_product:price" />
<mvt:else>
<mvt:assign name="l.new_color_item" value="''" />
<mvt:assign name="l.new_color_item:color" value="l.settings:outfit_product:color" />
<mvt:assign name="l.new_color_item:total_quantity" value="1" />
<mvt:assign name="l.new_color_item:total_price" value="l.settings:outfit_product:price" />
<mvt:assign name="l.result" value="miva_array_insert( l.color_items, l.new_color_item, -1 )" />
</mvt:if>
</mvt:foreach>
<mvt:assign name="g.mvt_debug" value="glosub( miva_array_serialize( l.color_items ), ',', asciichar( 10 ) )" />
<pre>&mvt:global:mvt_debug;</pre>
<p><i>Output: <pre>[1]:color=Black
[1]:total_price=71.96
[1]:total_quantity=4
[2]:color=Blue
[2]:total_price=70.97
[2]:total_quantity=3</pre></i></p>
var outfit_products = [
{
name: "Hat",
color: "Black",
price: 19.99
},
{
name: "T-Shirt",
color: "Blue",
price: 14.99
},
{
name: "T-Shirt",
color: "Blue",
price: 15.99
},
{
name: "Pants",
color: "Blue",
price: 39.99
},
{
name: "Socks",
color: "Black",
price: 5.99
},
{
name: "Socks",
color: "Black",
price: 5.99
},
{
name: "Shoes",
color: "Black",
price: 39.99
}
]
// Does the outfit list have a T-Shirt in it? - JavaScript: for
var found_shirt = false;
for (var i = 0, len = outfit_products.length; i < len; i++) {
var product = outfit_products[i];
if( product.name === 'T-Shirt' ) {
found_shirt = true;
break;
}
}
console.log('Does the outfit list have a T-Shirt in it? - JavaScript: for', found_shirt);
/* Output:
true
*/
// Does the outfit list have a T-Shirt in it? - JavaScript: Array.forEach
var found_shirt = false;
outfit_products.forEach(function(product){
if( product.name === 'T-Shirt' ) {
found_shirt = true;
}
});
console.log('Does the outfit list have a T-Shirt in it? - JavaScript: Array.forEach', found_shirt);
/* Output:
true
*/
// Does the outfit list have a T-Shirt in it? - JavaScript: Array.some
var found_shirt = outfit_products.some(function(product){
return product.name === 'T-Shirt';
});
console.log('Does the outfit list have a T-Shirt in it? - JavaScript: Array.some', found_shirt);
/* Output:
true
*/
// Which items in the outfit are blue? - JavaScript: for
var blue_products = [];
for (var i = 0, len = outfit_products.length; i < len; i++) {
var product = outfit_products[i];
if( product.color === 'Blue' ) {
blue_products.push(product);
}
};
console.log('Which items in the outfit are blue? - JavaScript: for', blue_products);
/* Output:
[
{
"name": "T-Shirt",
"color": "Blue",
"price": 14.99
},
{
"name": "T-Shirt",
"color": "Blue",
"price": 15.99
},
{
"name": "Pants",
"color": "Blue",
"price": 39.99
}
]
*/
// Which items in the outfit are blue? - JavaScript: Array.forEach
var blue_products = [];
outfit_products.forEach(function(product){
if( product.color === 'Blue' ) {
blue_products.push(product);
}
});
console.log('Which items in the outfit are blue? - JavaScript: Array.forEach', blue_products);
/* Output:
[
{
"name": "T-Shirt",
"color": "Blue",
"price": 14.99
},
{
"name": "T-Shirt",
"color": "Blue",
"price": 15.99
},
{
"name": "Pants",
"color": "Blue",
"price": 39.99
}
]
*/
// Which items in the outfit are blue? - JavaScript: Array.filter
var blue_products = outfit_products.filter(function(product){
return product.color === 'Blue';
});
console.log('Which items in the outfit are blue? - JavaScript: Array.filter', blue_products);
/* Output:
[
{
"name": "T-Shirt",
"color": "Blue",
"price": 14.99
},
{
"name": "T-Shirt",
"color": "Blue",
"price": 15.99
},
{
"name": "Pants",
"color": "Blue",
"price": 39.99
}
]
*/
// Sum up the prices & quantities for each color of item in the outfit - JavaScript: for
var totals = {};
for (var i = 0, len = outfit_products.length; i < len; i++) {
var product = outfit_products[i];
if( typeof totals[product.color] === 'object' ){
totals[product.color].total_quantity++;
totals[product.color].total_price += product.price;
}
else {
totals[product.color] = {
total_quantity: 1,
total_price: product.price
};
}
}
console.log('Sum up the prices & quantities for each color of item in the outfit - JavaScript: for', totals);
/* Output:
{
"Black": {
"total_quantity": 4,
"total_price": 71.96000000000001
},
"Blue": {
"total_quantity": 3,
"total_price": 70.97
}
}
*/
// Sum up the prices & quantities for each color of item in the outfit - JavaScript: Array.forEach
var totals = {};
outfit_products.forEach(function(product){
if( typeof totals[product.color] === 'undefined' ){
totals[product.color] = {
total_quantity: 1,
total_price: product.price
};
}
else {
totals[product.color].total_quantity++;
totals[product.color].total_price += product.price;
}
});
console.log('Sum up the prices & quantities for each color of item in the outfit - JavaScript: Array.forEach', totals);
/* Output:
{
"Black": {
"total_quantity": 4,
"total_price": 71.96000000000001
},
"Blue": {
"total_quantity": 3,
"total_price": 70.97
}
}
*/
// Sum up the prices & quantities for each color of item in the outfit - JavaScript: Array.reduce
var totals = outfit_products.reduce(function(accumulator_totals, product){
if( typeof accumulator_totals[product.color] === 'object' ){
accumulator_totals[product.color].total_quantity++;
accumulator_totals[product.color].total_price += product.price;
}
else {
accumulator_totals[product.color] = {
total_quantity: 1,
total_price: product.price
};
}
return accumulator_totals
}, {});
console.log('Sum up the prices & quantities for each color of item in the outfit - JavaScript: Array.reduce', totals);
/* Output:
{
"Black": {
"total_quantity": 4,
"total_price": 71.96000000000001
},
"Blue": {
"total_quantity": 3,
"total_price": 70.97
}
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment