Array Operations¶
This guide demonstrates working with arrays in EverSharp, including filtering, mapping, reducing, sorting, and complex data transformations.
Creating Arrays¶
Array Literals¶
// Empty array
empty = [];
// Array of numbers
numbers = [1, 2, 3, 4, 5];
// Array of strings
names = ["Alice", "Bob", "Charlie"];
// Mixed types (not recommended but allowed)
mixed = [1, "hello", true, null];
// Array of objects
policies = [
{ id: 1, premium: 1200, status: "Active" },
{ id: 2, premium: 850, status: "Pending" },
{ id: 3, premium: 1500, status: "Active" },
];
Using $Array Constructor¶
// Create array from items
arr = $Array(10, 20, 30); // [10, 20, 30]
// Create empty array
empty = $Array(); // []
Accessing Array Elements¶
By Index¶
numbers = [10, 20, 30, 40, 50];
first = numbers[0]; // 10
second = numbers[1]; // 20
last = numbers[4]; // 50
// Get array length
count = numbers.Length; // 5
Filtering Arrays¶
Filter Method¶
The .Filter() method selects elements that match a condition:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Get even numbers
evens = numbers.Filter((n) => n % 2 == 0);
// Result: [2, 4, 6, 8, 10]
// Get numbers greater than 5
large = numbers.Filter((n) => n > 5);
// Result: [6, 7, 8, 9, 10]
Filtering Objects¶
policies = [
{ id: 1, premium: 1200, status: "Active" },
{ id: 2, premium: 850, status: "Lapsed" },
{ id: 3, premium: 1500, status: "Active" },
{ id: 4, premium: 950, status: "Pending" },
];
// Get only active policies
active = policies.Filter((p) => p.status == "Active");
// Result: [{ id: 1, ... }, { id: 3, ... }]
// Get high-value policies (premium >= 1000)
highValue = policies.Filter((p) => p.premium >= 1000);
// Result: [{ id: 1, ... }, { id: 3, ... }]
// Multiple conditions
activeHighValue = policies.Filter(
(p) => p.status == "Active" && p.premium >= 1000
);
// Result: [{ id: 1, ... }, { id: 3, ... }]
Finding Elements¶
Find Method¶
Find the first element matching a condition:
policies = [
{ id: 1, premium: 1200 },
{ id: 2, premium: 850 },
{ id: 3, premium: 1500 },
];
// Find policy with id = 2
policy = policies.Find((p) => p.id == 2);
// Result: { id: 2, premium: 850 }
// Find first policy with premium > 1000
expensive = policies.Find((p) => p.premium > 1000);
// Result: { id: 1, premium: 1200 }
Any and All Methods¶
Check if any or all elements match:
numbers = [2, 4, 6, 8, 10];
// Check if any number is greater than 5
hasLarge = numbers.Any((n) => n > 5); // true
// Check if all numbers are even
allEven = numbers.All((n) => n % 2 == 0); // true
// Check if all numbers are greater than 5
allLarge = numbers.All((n) => n > 5); // false
Transforming Arrays¶
Map Method¶
Transform each element:
numbers = [1, 2, 3, 4, 5];
// Square each number
squares = numbers.Map((n) => n * n);
// Result: [1, 4, 9, 16, 25]
// Double each number
doubled = numbers.Map((n) => n * 2);
// Result: [2, 4, 6, 8, 10]
Mapping Objects¶
policies = [
{ id: 1, premium: 1200, status: "Active" },
{ id: 2, premium: 850, status: "Lapsed" },
{ id: 3, premium: 1500, status: "Active" },
];
// Extract just the premiums
premiums = policies.Map((p) => p.premium);
// Result: [1200, 850, 1500]
// Create summary objects
summaries = policies.Map((p) => {
return {
policyId: p.id,
amount: p.premium,
isActive: p.status == "Active",
};
});
// Result: [{ policyId: 1, amount: 1200, isActive: true }, ...]
Map with Index¶
The second parameter is the index:
items = ["A", "B", "C"];
// Add index to each item
numbered = items.Map((item, index) => {
return $ToString(index + 1) + ". " + item;
});
// Result: ["1. A", "2. B", "3. C"]
Reducing Arrays¶
Sum Numbers¶
numbers = [10, 20, 30, 40, 50];
// Sum all numbers
total = numbers.ReduceToNum((sum, n) => sum + n, 0);
// Result: 150
Calculate Average¶
values = [85, 90, 78, 92, 88];
total = values.ReduceToNum((sum, n) => sum + n, 0);
average = total / values.Length;
// Result: 86.6
Find Maximum¶
numbers = [45, 12, 89, 23, 67];
maximum = numbers.ReduceToNum((max, n) => {
if (n > max) {
return n;
} else {
return max;
}
}, numbers[0]);
// Result: 89
Reduce to Object¶
policies = [
{ status: "Active", premium: 1200 },
{ status: "Active", premium: 850 },
{ status: "Lapsed", premium: 1500 },
];
// Count by status
summary = policies.Reduce(
(acc, p) => {
if (p.status == "Active") {
acc.activeCount = acc.activeCount + 1;
acc.activePremium = acc.activePremium + p.premium;
} else {
acc.lapsedCount = acc.lapsedCount + 1;
acc.lapsedPremium = acc.lapsedPremium + p.premium;
}
return acc;
},
{
activeCount: 0,
activePremium: 0,
lapsedCount: 0,
lapsedPremium: 0,
}
);
// Result: { activeCount: 2, activePremium: 2050, lapsedCount: 1, lapsedPremium: 1500 }
Sorting Arrays¶
Sort Numbers¶
numbers = [45, 12, 89, 23, 67];
// Sort ascending
ascending = numbers.OrderBy((n) => n);
// Result: [12, 23, 45, 67, 89]
// Sort descending
descending = numbers.OrderByDescending((n) => n);
// Result: [89, 67, 45, 23, 12]
Sort Objects¶
policies = [
{ id: 3, premium: 1500 },
{ id: 1, premium: 850 },
{ id: 2, premium: 1200 },
];
// Sort by premium (ascending)
byPremium = policies.OrderBy((p) => p.premium);
// Result: [{ id: 1, premium: 850 }, { id: 2, premium: 1200 }, { id: 3, premium: 1500 }]
// Sort by id (ascending)
byId = policies.OrderBy((p) => p.id);
// Result: [{ id: 1, ... }, { id: 2, ... }, { id: 3, ... }]
// Sort by premium (descending)
byPremiumDesc = policies.OrderByDescending((p) => p.premium);
// Result: [{ id: 3, premium: 1500 }, { id: 2, premium: 1200 }, { id: 1, premium: 850 }]
Slicing and Pagination¶
Take and Skip¶
numbers = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
// Take first 3
first3 = numbers.Take(3);
// Result: [10, 20, 30]
// Skip first 3
rest = numbers.Skip(3);
// Result: [40, 50, 60, 70, 80, 90, 100]
// Pagination: Page 2 with 3 items per page
page = 2;
pageSize = 3;
pageData = numbers.Skip((page - 1) * pageSize).Take(pageSize);
// Result: [40, 50, 60]
Slice Method¶
numbers = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
// Get elements from index 2 to 5 (exclusive)
subset = numbers.Slice(2, 5);
// Result: [30, 40, 50]
// Get from index 5 to end
fromFive = numbers.Slice(5, numbers.Length);
// Result: [60, 70, 80, 90, 100]
Modifying Arrays¶
Adding Elements¶
numbers = [10, 20, 30];
// Add to end
numbers.Push(40);
// numbers is now: [10, 20, 30, 40]
// Insert at specific position
numbers.Insert(1, 15);
// numbers is now: [10, 15, 20, 30, 40]
// Add multiple elements
numbers.AddRange([50, 60, 70]);
// numbers is now: [10, 15, 20, 30, 40, 50, 60, 70]
Removing Elements¶
numbers = [10, 20, 30, 40, 50];
// Remove by value
numbers.Remove(30);
// numbers is now: [10, 20, 40, 50]
// Remove by index
numbers.RemoveAt(1);
// numbers is now: [10, 40, 50]
// Clear all elements
numbers.Clear();
// numbers is now: []
Array Utilities¶
Distinct Values¶
Reverse Array¶
Join Array¶
words = ["Hello", "World", "!"];
sentence = words.Join(" ");
// Result: "Hello World !"
// Join with comma
csv = words.Join(",");
// Result: "Hello,World,!"
IndexOf¶
numbers = [10, 20, 30, 40, 50];
index = numbers.IndexOf(30);
// Result: 2
// Not found returns -1
notFound = numbers.IndexOf(99);
// Result: -1
Practical Examples¶
Example 1: Calculate Total Premium¶
policies = [
{ id: 1, premium: 1200 },
{ id: 2, premium: 850 },
{ id: 3, premium: 1500 },
{ id: 4, premium: 950 },
];
totalPremium = policies
.Map((p) => p.premium)
.ReduceToNum((sum, p) => sum + p, 0);
// Result: 4500
Example 2: Filter and Sort¶
policies = [
{ id: 3, premium: 1500, status: "Active" },
{ id: 1, premium: 850, status: "Lapsed" },
{ id: 4, premium: 1200, status: "Active" },
{ id: 2, premium: 950, status: "Active" },
];
// Get active policies sorted by premium descending
activeSorted = policies
.Filter((p) => p.status == "Active")
.OrderByDescending((p) => p.premium);
// Result: [{ id: 3, premium: 1500 }, { id: 4, premium: 1200 }, { id: 2, premium: 950 }]
Example 3: Group and Count¶
claims = [
{ type: "Auto", amount: 1500 },
{ type: "Home", amount: 3000 },
{ type: "Auto", amount: 2500 },
{ type: "Life", amount: 5000 },
{ type: "Auto", amount: 1200 },
];
// Count by type
summary = claims.Reduce((acc, claim) => {
type = claim.type;
// Find existing type in accumulator
existing = acc.Find((item) => item.type == type);
if (existing == null) {
// Add new type
acc.Push({
type: type,
count: 1,
total: claim.amount,
});
} else {
// Update existing type
existing.count = existing.count + 1;
existing.total = existing.total + claim.amount;
}
return acc;
}, []);
// Result: [
// { type: "Auto", count: 3, total: 5200 },
// { type: "Home", count: 1, total: 3000 },
// { type: "Life", count: 1, total: 5000 }
// ]
Example 4: Top N Items¶
policies = [
{ id: 1, premium: 1200 },
{ id: 2, premium: 850 },
{ id: 3, premium: 1500 },
{ id: 4, premium: 950 },
{ id: 5, premium: 1800 },
];
// Get top 3 policies by premium
top3 = policies.OrderByDescending((p) => p.premium).Take(3);
// Result: [{ id: 5, premium: 1800 }, { id: 3, premium: 1500 }, { id: 1, premium: 1200 }]
Example 5: Calculate Statistics¶
calculateStats = function (numbers) {
count = numbers.Length;
if (count == 0) {
return null;
}
// Sum
sum = numbers.ReduceToNum((total, n) => total + n, 0);
// Average
avg = sum / count;
// Min and Max
min = numbers.ReduceToNum((m, n) => {
if (n < m) {
return n;
} else {
return m;
}
}, numbers[0]);
max = numbers.ReduceToNum((m, n) => {
if (n > m) {
return n;
} else {
return m;
}
}, numbers[0]);
return {
count: count,
sum: sum,
average: avg,
min: min,
max: max,
};
};
premiums = [1200, 850, 1500, 950, 1800];
stats = calculateStats(premiums);
// Result: {
// count: 5,
// sum: 6300,
// average: 1260,
// min: 850,
// max: 1800
// }
Example 6: Flatten Nested Arrays¶
nested = [
[1, 2, 3],
[4, 5],
[6, 7, 8, 9],
];
// Flatten to single array
flattened = nested.ReduceToArr((acc, arr) => {
// Add all elements from arr to acc
arr.ForEach((n) => {
acc.Push(n);
});
return acc;
}, []);
// Result: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Example 7: Remove Duplicates by Property¶
customers = [
{ id: 1, name: "Alice", email: "alice@example.com" },
{ id: 2, name: "Bob", email: "bob@example.com" },
{ id: 3, name: "Alice", email: "alice@example.com" },
{ id: 4, name: "Charlie", email: "charlie@example.com" },
];
// Remove duplicates by email
uniqueByEmail = customers.Reduce((acc, customer) => {
// Check if email already exists
exists = acc.Any((c) => c.email == customer.email);
if (!exists) {
acc.Push(customer);
}
return acc;
}, []);
// Result: [
// { id: 1, name: "Alice", email: "alice@example.com" },
// { id: 2, name: "Bob", email: "bob@example.com" },
// { id: 4, name: "Charlie", email: "charlie@example.com" }
// ]
Example 8: Partition Array¶
Split array into groups based on condition:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
partition = numbers.Reduce(
(acc, n) => {
if (n % 2 == 0) {
acc.evens.Push(n);
} else {
acc.odds.Push(n);
}
return acc;
},
{ evens: [], odds: [] }
);
// Result: {
// evens: [2, 4, 6, 8, 10],
// odds: [1, 3, 5, 7, 9]
// }
Example 9: Search and Replace¶
policies = [
{ id: 1, status: "Active" },
{ id: 2, status: "Pending" },
{ id: 3, status: "Active" },
];
// Update status of policy with id = 2
updated = policies.Map((p) => {
if (p.id == 2) {
// Create new object with updated status
return {
id: p.id,
status: "Active",
};
} else {
return p;
}
});
// Result: [
// { id: 1, status: "Active" },
// { id: 2, status: "Active" }, // Updated
// { id: 3, status: "Active" }
// ]
Example 10: Complex Chaining¶
transactions = [
{ date: $ToDate("2024-01-15"), amount: 1200, type: "Premium" },
{ date: $ToDate("2024-02-20"), amount: -500, type: "Claim" },
{ date: $ToDate("2024-03-10"), amount: 1200, type: "Premium" },
{ date: $ToDate("2024-04-05"), amount: -750, type: "Claim" },
{ date: $ToDate("2024-05-15"), amount: 1200, type: "Premium" },
];
// Calculate total premiums for current year
currentYear = $Year($Today());
totalPremiums = transactions
.Filter((t) => t.type == "Premium")
.Filter((t) => $Year(t.date) == currentYear)
.Map((t) => t.amount)
.ReduceToNum((sum, amt) => sum + amt, 0);
// Result: 3600 (sum of all Premium amounts)
Common Patterns¶
Check if Array is Empty¶
Safe Array Access¶
getItemSafe = function (array, index) {
if (index >= 0 && index < array.Length) {
return array[index];
} else {
return null;
}
};
numbers = [10, 20, 30];
item = getItemSafe(numbers, 5); // null (index out of range)
Convert to Lookup Object¶
items = [
{ id: "A", value: 10 },
{ id: "B", value: 20 },
{ id: "C", value: 30 },
];
// Note: EverSharp doesn't have direct object key manipulation,
// so we'll use Find for lookup instead
lookup = function (arr, id) {
item = arr.Find((x) => x.id == id);
if (item != null) {
return item.value;
} else {
return null;
}
};
value = lookup(items, "B"); // 20
Best Practices¶
Chain Operations for Clarity¶
// Good: clear chain of operations
result = items
.Filter((x) => x.active)
.OrderBy((x) => x.priority)
.Take(10);
// Less clear: nested function calls
result = items
.Filter((x) => x.active)
.OrderBy((x) => x.priority)
.Take(10);
Use Descriptive Lambda Parameters¶
// Good: descriptive name
customers.Filter((customer) => customer.age >= 18);
// Less clear: single letter
customers.Filter((c) => c.age >= 18);
Avoid Modifying Arrays During Iteration¶
// Don't modify array while iterating
// Instead, create a new array with the changes
// Wrong:
// arr.ForEach((item) => {
// arr.Remove(item); // Modifying during iteration
// });
// Correct: use Filter to create new array
newArr = arr.Filter((item) => /* condition to keep */);
Next Steps¶
- Object Manipulation - Working with objects in arrays
- Business Rules - Complex calculations using arrays
- Basic Calculations - Foundation operations
See Also¶
- Array Functions - Complete array function reference
- Lambda Expressions - Lambda syntax and patterns
- Arrays Data Type - Array fundamentals