Skip to content

⚡ ARRAY › From Indexed Values Generator — GTM Variable Template for Array

VARIABLES › ARRAY
⚡ ARRAY › From Indexed Values EXTENDED Array
Direct (.tpl)

Generates an array from indexed table values, ordered by index.


GTM Utilities

Access GTM-specific APIs: dataLayer, debug mode, container settings.

GA4 Ecommerce

Build and transform ecommerce data structures for GA4 event tracking.

Sorting

Order arrays and collections by values, keys, or custom comparators.


Transform with mapper
INPUT
Indexed Values: [{ind: 0, val: 'hello'}, {ind: 1, val: 'world'}, {val: 'extra'}]
Append unindexed values at the end: true
Mapper Function (optional): val => val.toUpperCase()
OUTPUT
['HELLO', 'WORLD', 'EXTRA']
Array ordered by index
INPUT
Indexed Values: [{ind: 0, val: 'first'}, {ind: 2, val: 'third'}, {ind: 1, val: 'second'}]
Append unindexed values at the end: true
OUTPUT
['first', 'second', 'third']

This is what you'll see when you open this variable in Google Tag Manager. Hover the icons for details.

⚡ ARRAY › From Indexed Values
ARRAY ⬇
Indexed Values
💾 Define values with optional indices.

Index column:
  • Valid indices: Non-negative numbers (0, 1, 2, ...)
  • Invalid/empty indices: Values are appended at the end (if enabled)
  • Gaps in indices: Filled with undefined

Value column:
  • Any value (string, number, variable, etc.)
IndexValue
✓ When enabled, values without valid indices are appended after the indexed values. When disabled, unindexed values are excluded from the result.
Value Processing
Mapper Function (optional)
⚙️ Optional function to transform each individual value before adding it to the array: val => transformedVal

Use this for:
  • Trim whitespace: val => val.trim()
  • Parse numbers: val => parseFloat(val)
  • Transform case: val => val.toUpperCase()
  • Add prefix: val => 'item_' + val

Note: This applies to each value individually, including both indexed and unindexed values.
Result Handling
Output Function (optional)
⚙️ Optional function to transform the entire array before returning it: arr => transformedArr

Use this for:
  • Remove gaps: arr => arr.filter(x => x !== undefined)
  • Convert to string: arr => arr.join(',')
  • Reverse array: arr => arr.reverse()

Note: This applies to the complete array after all values have been processed and positioned.
Indexed Values table
IndexValue
buildArrayFromIndexedValues()


📜 View Implementation Code
/**
* Converts indexed objects into a properly ordered array with optional unindexed values appended.
*
* @param {Array<{ind?: number, val: any}>} data.ivl - Array of objects with optional index (ind) and value (val).
* @param {boolean} [data.aui=true] - Whether to append unindexed values at the end.
* @param {Function} [data.map] - Optional function to transform each value before adding to array.
* @param {Function|string} [data.out] - Optional output handler.
*
* @returns {Array} Ordered array with indexed values and optionally appended unindexed values.
*
* @framework ggLowCodeGTMKit
*/
const getType = require('getType');
const makeNumber = require('makeNumber');
const buildArrayFromIndexedValues = function(ivl, aui, mapper) {
const indexedObjects = getType(ivl) === 'array' && ivl || [];
const appendUnindexed = typeof aui !== 'undefined' ? aui : true;
if (typeof mapper !== 'function') mapper = function(x) { return x; };
const indexed = [];
const unindexed = [];
indexedObjects.forEach(obj => {
if (obj && obj.hasOwnProperty('ind') && obj.ind !== null && obj.ind !== undefined && obj.ind !== '') {
const idx = makeNumber(obj.ind);
if (typeof idx === 'number' && idx >= 0 && idx === idx) {
indexed.push(obj);
} else if (obj.hasOwnProperty('val')) {
unindexed.push(obj);
}
} else if (obj && obj.hasOwnProperty('val')) {
unindexed.push(obj);
}
});
indexed.sort((a, b) => makeNumber(a.ind) - makeNumber(b.ind));
let maxIndex = -1;
indexed.forEach(obj => {
const idx = makeNumber(obj.ind);
if (idx > maxIndex) {
maxIndex = idx;
}
});
const result = [];
result.length = maxIndex + 1;
indexed.forEach(obj => {
result[makeNumber(obj.ind)] = mapper(obj.val);
});
if (appendUnindexed) {
unindexed.forEach(obj => result.push(mapper(obj.val)));
}
return result;
};
const safeFunction = fn => typeof fn === 'function' ? fn : x => x;
const out = safeFunction(data.out);
return out(buildArrayFromIndexedValues(data.ivl, data.aui, safeFunction(data.map)));
🧪 View Test Scenarios (11 tests)
✅ '[example] Transform with mapper'
✅ '[example] Array ordered by index'
✅ Array with gaps - should fill with undefined
✅ Unindexed values appended - should add at the end
✅ Unindexed values not appended - should exclude them
✅ Mixed indexed and unindexed with gaps
✅ Invalid indices - should treat as unindexed
✅ Empty array - should return empty array
✅ Duplicate indices - last one should win
✅ Output function to remove undefined - should filter gaps
✅ Unsorted indices - should sort properly