use for-of statements to replace for and for-in

This commit is contained in:
MaysWind
2025-09-14 01:40:53 +08:00
parent 67bc81d3e2
commit 4700446ca0
38 changed files with 389 additions and 597 deletions
+37 -67
View File
@@ -1,3 +1,4 @@
import { itemAndIndex, keys, keysIfValueEquals, values } from '@/core/base.ts';
import { AccountType, AccountCategory } from '@/core/account.ts';
import { PARENT_ACCOUNT_CURRENCY_PLACEHOLDER } from '@/consts/currency.ts';
import { type AccountBalance, type CategorizedAccount, type AccountCategoriesWithVisibleCount, Account } from '@/models/account.ts';
@@ -5,9 +6,7 @@ import { type AccountBalance, type CategorizedAccount, type AccountCategoriesWit
export function getCategorizedAccountsMap(allAccounts: Account[]): Record<number, CategorizedAccount> {
const ret: Record<number, CategorizedAccount> = {};
for (let i = 0; i < allAccounts.length; i++) {
const account = allAccounts[i];
for (const account of allAccounts) {
if (!ret[account.category]) {
const categoryInfo = AccountCategory.valueOf(account.category);
@@ -21,8 +20,10 @@ export function getCategorizedAccountsMap(allAccounts: Account[]): Record<number
}
}
if (ret[account.category]) {
const accountList = ret[account.category].accounts;
const categorizedAccount = ret[account.category];
if (categorizedAccount) {
const accountList = categorizedAccount.accounts;
accountList.push(account);
}
}
@@ -35,15 +36,16 @@ export function getCategorizedAccounts(allAccounts: Account[]): CategorizedAccou
const allCategories = AccountCategory.values();
const categorizedAccounts = getCategorizedAccountsMap(allAccounts);
for (let i = 0; i < allCategories.length; i++) {
const category = allCategories[i];
for (const category of allCategories) {
if (!categorizedAccounts[category.type]) {
continue;
}
const accountCategory = categorizedAccounts[category.type];
ret.push(accountCategory);
if (accountCategory) {
ret.push(accountCategory);
}
}
return ret;
@@ -56,14 +58,11 @@ export function getAccountMapByName(allAccounts: Account[]): Record<string, Acco
return ret;
}
for (let i = 0; i < allAccounts.length; i++) {
const account = allAccounts[i];
for (const account of allAccounts) {
if (account.type === AccountType.SingleAccount.type) {
ret[account.name] = account;
} else if (account.type === AccountType.MultiSubAccounts.type && account.subAccounts) {
for (let j = 0; j < account.subAccounts.length; j++) {
const subAccount = account.subAccounts[j];
for (const subAccount of account.subAccounts) {
ret[subAccount.name] = subAccount;
}
}
@@ -76,28 +75,26 @@ export function getCategorizedAccountsWithVisibleCount(categorizedAccountsMap: R
const ret: AccountCategoriesWithVisibleCount[] = [];
const allCategories = AccountCategory.values();
for (let i = 0; i < allCategories.length; i++) {
const accountCategory = allCategories[i];
for (const accountCategory of allCategories) {
const categorizedAccount = categorizedAccountsMap[accountCategory.type];
if (!categorizedAccountsMap[accountCategory.type] || !categorizedAccountsMap[accountCategory.type].accounts) {
if (!categorizedAccount || !categorizedAccount.accounts) {
continue;
}
const allAccounts = categorizedAccountsMap[accountCategory.type].accounts;
const allAccounts = categorizedAccount.accounts;
const allSubAccounts: Record<string, Account[]> = {};
const allVisibleSubAccountCounts: Record<string, number> = {};
const allFirstVisibleSubAccountIndexes: Record<string, number> = {};
let allVisibleAccountCount = 0;
let firstVisibleAccountIndex = -1;
for (let j = 0; j < allAccounts.length; j++) {
const account = allAccounts[j];
for (const [account, accountIndex] of itemAndIndex(allAccounts)) {
if (!account.hidden) {
allVisibleAccountCount++;
if (firstVisibleAccountIndex === -1) {
firstVisibleAccountIndex = j;
firstVisibleAccountIndex = accountIndex;
}
}
@@ -105,14 +102,12 @@ export function getCategorizedAccountsWithVisibleCount(categorizedAccountsMap: R
let visibleSubAccountCount = 0;
let firstVisibleSubAccountIndex = -1;
for (let k = 0; k < account.subAccounts.length; k++) {
const subAccount = account.subAccounts[k];
for (const [subAccount, subAccountIndex] of itemAndIndex(account.subAccounts)) {
if (!subAccount.hidden) {
visibleSubAccountCount++;
if (firstVisibleSubAccountIndex === -1) {
firstVisibleSubAccountIndex = k;
firstVisibleSubAccountIndex = subAccountIndex;
}
}
}
@@ -147,16 +142,14 @@ export function getAllFilteredAccountsBalance(categorizedAccounts: Record<number
const allAccountCategories = AccountCategory.values();
const ret: AccountBalance[] = [];
for (let categoryIdx = 0; categoryIdx < allAccountCategories.length; categoryIdx++) {
const accountCategory = allAccountCategories[categoryIdx];
for (const accountCategory of allAccountCategories) {
const categorizedAccount = categorizedAccounts[accountCategory.type];
if (!categorizedAccounts[accountCategory.type] || !categorizedAccounts[accountCategory.type].accounts) {
if (!categorizedAccount || !categorizedAccount.accounts) {
continue;
}
for (let accountIdx = 0; accountIdx < categorizedAccounts[accountCategory.type].accounts.length; accountIdx++) {
const account = categorizedAccounts[accountCategory.type].accounts[accountIdx];
for (const account of categorizedAccount.accounts) {
if (account.hidden || !accountFilter(account)) {
continue;
}
@@ -169,9 +162,7 @@ export function getAllFilteredAccountsBalance(categorizedAccounts: Record<number
currency: account.currency
});
} else if (account.type === AccountType.MultiSubAccounts.type && account.subAccounts) {
for (let subAccountIdx = 0; subAccountIdx < account.subAccounts.length; subAccountIdx++) {
const subAccount = account.subAccounts[subAccountIdx];
for (const subAccount of account.subAccounts) {
if (subAccount.hidden || !accountFilter(subAccount)) {
continue;
}
@@ -197,13 +188,7 @@ export function getFinalAccountIdsByFilteredAccountIds(allAccountsMap: Record<st
return finalAccountIds;
}
for (const accountId in allAccountsMap) {
if (!Object.prototype.hasOwnProperty.call(allAccountsMap, accountId)) {
continue;
}
const account = allAccountsMap[accountId];
for (const account of values(allAccountsMap)) {
if (filteredAccountIds && !isAccountOrSubAccountsAllChecked(account, filteredAccountIds)) {
continue;
}
@@ -225,13 +210,13 @@ export function getUnifiedSelectedAccountsCurrencyOrDefaultCurrency(allAccountsM
let accountCurrency = '';
for (const accountId in selectedAccountIds) {
if (!Object.prototype.hasOwnProperty.call(selectedAccountIds, accountId)) {
for (const accountId of keysIfValueEquals(selectedAccountIds, true)) {
const account = allAccountsMap[accountId];
if (!account) {
continue;
}
const account = allAccountsMap[accountId];
if (account.currency === PARENT_ACCOUNT_CURRENCY_PLACEHOLDER) {
continue;
}
@@ -258,19 +243,14 @@ export function selectAccountOrSubAccounts(filterAccountIds: Record<string, bool
return;
}
for (let i = 0; i < account.subAccounts.length; i++) {
const subAccount = account.subAccounts[i];
for (const subAccount of account.subAccounts) {
filterAccountIds[subAccount.id] = value;
}
}
}
export function selectAll(filterAccountIds: Record<string, boolean>, allAccountsMap: Record<string, Account>, skipHiddenAccount: boolean): void {
for (const accountId in filterAccountIds) {
if (!Object.prototype.hasOwnProperty.call(filterAccountIds, accountId)) {
continue;
}
for (const accountId of keys(filterAccountIds)) {
const account = allAccountsMap[accountId];
if (skipHiddenAccount && account && account.hidden) {
@@ -284,11 +264,7 @@ export function selectAll(filterAccountIds: Record<string, boolean>, allAccounts
}
export function selectNone(filterAccountIds: Record<string, boolean>, allAccountsMap: Record<string, Account>, skipHiddenAccount: boolean): void {
for (const accountId in filterAccountIds) {
if (!Object.prototype.hasOwnProperty.call(filterAccountIds, accountId)) {
continue;
}
for (const accountId of keys(filterAccountIds)) {
const account = allAccountsMap[accountId];
if (skipHiddenAccount && account && account.hidden) {
@@ -302,11 +278,7 @@ export function selectNone(filterAccountIds: Record<string, boolean>, allAccount
}
export function selectInvert(filterAccountIds: Record<string, boolean>, allAccountsMap: Record<string, Account>, skipHiddenAccount: boolean): void {
for (const accountId in filterAccountIds) {
if (!Object.prototype.hasOwnProperty.call(filterAccountIds, accountId)) {
continue;
}
for (const accountId of keys(filterAccountIds)) {
const account = allAccountsMap[accountId];
if (skipHiddenAccount && account && account.hidden) {
@@ -324,8 +296,7 @@ export function isAccountOrSubAccountsAllChecked(account: Account, filterAccount
return !filterAccountIds[account.id];
}
for (let i = 0; i < account.subAccounts.length; i++) {
const subAccount = account.subAccounts[i];
for (const subAccount of account.subAccounts) {
if (filterAccountIds[subAccount.id]) {
return false;
}
@@ -341,8 +312,7 @@ export function isAccountOrSubAccountsHasButNotAllChecked(account: Account, filt
let checkedCount = 0;
for (let i = 0; i < account.subAccounts.length; i++) {
const subAccount = account.subAccounts[i];
for (const subAccount of account.subAccounts) {
if (!filterAccountIds[subAccount.id]) {
checkedCount++;
}
+2 -2
View File
@@ -20,8 +20,8 @@ export function getColorsInRows(allColorValues: ColorValue[], itemPerRow: number
ret[++rowCount] = [];
}
ret[rowCount].push({
color: allColorValues[i]
ret[rowCount]!.push({
color: allColorValues[i] as ColorValue
});
}
+13 -8
View File
@@ -4,12 +4,15 @@ import { replaceAll } from './common.ts';
import logger from './logger.ts';
type Operator = '+' | '-' | '*' | '/';
type OperatorAndParenthesis = Operator | '(' | ')';
const maxAllowedDecimalCount = 6;
const normalizeFactor: number = 1000000;
const normalizedDecimalsMaxZeroString: string = '000000';
const normalizedNumberToAmountFactor: number = 10000; // 1000000 / 100
const operatorPriority: Record<string, number> = {
const operatorPriority: Record<Operator, number> = {
'+': 1,
'-': 1,
'*': 2,
@@ -48,20 +51,20 @@ function checkNumberRange(num: number): void {
function toPostfixExprTokens(expr: string): string[] | null {
const finalTokens: string[] = [];
const operatorStack: string[] = [];
const operatorStack: OperatorAndParenthesis[] = [];
let currentNumberBuilder = '';
let isLastTokenOperator = true;
expr = replaceAll(expr, ' ', '');
for (let i = 0; i < expr.length; i++) {
const ch = expr[i];
const ch = expr[i] as string;
// number
if ('0' <= ch && ch <= '9' || ch === '.') {
currentNumberBuilder += ch;
continue
} else if (ch === '-' && i + 1 < expr.length && '0' <= expr[i + 1] && expr[i + 1] <= '9' && currentNumberBuilder.length === 0 && isLastTokenOperator) {
} else if (ch === '-' && i + 1 < expr.length && '0' <= (expr[i + 1] as string) && (expr[i + 1] as string) <= '9' && currentNumberBuilder.length === 0 && isLastTokenOperator) {
currentNumberBuilder += ch;
continue
}
@@ -84,13 +87,15 @@ function toPostfixExprTokens(expr: string): string[] | null {
}
while (operatorStack.length > 0) {
const topOperator = operatorStack[operatorStack.length - 1];
const topOperator = operatorStack[operatorStack.length - 1] as OperatorAndParenthesis;
if (topOperator === '(') {
break;
}
if (operatorPriority[topOperator] >= operatorPriority[ch]) {
const isCurrentOperator = topOperator === '+' || topOperator === '-' || topOperator === '*' || topOperator === '/';
if (isCurrentOperator && operatorPriority[topOperator] >= operatorPriority[ch]) {
finalTokens.push(topOperator);
operatorStack.pop();
} else {
@@ -154,7 +159,7 @@ function evaluatePostfixExpr(tokens: string[]): number | null {
const stack: number[] = [];
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
const token = tokens[i] as string;
switch (token) {
case '+':
@@ -211,7 +216,7 @@ function evaluatePostfixExpr(tokens: string[]): number | null {
return null;
}
return stack[0];
return stack[0] as number;
}
export function evaluateExpressionToAmount(expr: string): number | undefined {
if (!expr) {
+3 -3
View File
@@ -13,8 +13,8 @@ import { isDefined, isString, isNumber, replaceAll, removeAll } from './common.t
export function sumAmounts(amounts: number[]): number {
let sum = 0;
for (let i = 0; i < amounts.length; i++) {
sum += amounts[i];
for (const amount of amounts) {
sum += amount;
}
return sum;
@@ -292,7 +292,7 @@ export function formatExchangeRateAmount(exchangeRateAmount: number, options: Nu
}
}
export function getAdaptiveDisplayAmountRate(amount1: number, amount2: number, fromExchangeRate: { rate: string }, toExchangeRate: { rate: string }, options: NumberFormatOptions): string | null {
export function getAdaptiveDisplayAmountRate(amount1: number, amount2: number, options: NumberFormatOptions, fromExchangeRate?: { rate: string }, toExchangeRate?: { rate: string }): string | null {
const numeralSystem = options.numeralSystem || NumeralSystem.Default;
if (!amount1 || !amount2 || amount1 === amount2) {
+3 -5
View File
@@ -1,3 +1,5 @@
import { keys } from '@/core/base.ts';
import type {
ApplicationSettingKey,
ApplicationSettingValue,
@@ -28,11 +30,7 @@ function getStoredApplicationSettings(): BaseApplicationSetting {
export function getApplicationSettings(): ApplicationSettings {
const storedApplicationSettings = getStoredApplicationSettings();
for (const key in storedApplicationSettings) {
if (!Object.prototype.hasOwnProperty.call(storedApplicationSettings, key)) {
continue;
}
for (const key of keys(storedApplicationSettings)) {
if (typeof(DEFAULT_APPLICATION_SETTINGS[key]) === 'object') {
storedApplicationSettings[key] = Object.assign({}, DEFAULT_APPLICATION_SETTINGS[key], storedApplicationSettings[key]);
}
+11 -10
View File
@@ -1,8 +1,9 @@
import { reversed } from '@/core/base.ts';
import { TransactionTag } from '@/models/transaction_tag.ts';
export function isNoAvailableTag(tags: TransactionTag[], showHidden: boolean): boolean {
for (let i = 0; i < tags.length; i++) {
if (showHidden || !tags[i].hidden) {
for (const tag of tags) {
if (showHidden || !tag.hidden) {
return false;
}
}
@@ -13,8 +14,8 @@ export function isNoAvailableTag(tags: TransactionTag[], showHidden: boolean): b
export function getAvailableTagCount(tags: TransactionTag[], showHidden: boolean): number {
let count = 0;
for (let i = 0; i < tags.length; i++) {
if (showHidden || !tags[i].hidden) {
for (const tag of tags) {
if (showHidden || !tag.hidden) {
count++;
}
}
@@ -23,9 +24,9 @@ export function getAvailableTagCount(tags: TransactionTag[], showHidden: boolean
}
export function getFirstShowingId(tags: TransactionTag[], showHidden: boolean): string | null {
for (let i = 0; i < tags.length; i++) {
if (showHidden || !tags[i].hidden) {
return tags[i].id;
for (const tag of tags) {
if (showHidden || !tag.hidden) {
return tag.id;
}
}
@@ -33,9 +34,9 @@ export function getFirstShowingId(tags: TransactionTag[], showHidden: boolean):
}
export function getLastShowingId(tags: TransactionTag[], showHidden: boolean): string | null {
for (let i = tags.length - 1; i >= 0; i--) {
if (showHidden || !tags[i].hidden) {
return tags[i].id;
for (const tag of reversed(tags)) {
if (showHidden || !tag.hidden) {
return tag.id;
}
}
+11 -10
View File
@@ -1,8 +1,9 @@
import { reversed } from '@/core/base.ts';
import { TransactionTemplate } from '@/models/transaction_template.ts';
export function isNoAvailableTemplate(templates: TransactionTemplate[], showHidden: boolean): boolean {
for (let i = 0; i < templates.length; i++) {
if (showHidden || !templates[i].hidden) {
for (const template of templates) {
if (showHidden || !template.hidden) {
return false;
}
}
@@ -13,8 +14,8 @@ export function isNoAvailableTemplate(templates: TransactionTemplate[], showHidd
export function getAvailableTemplateCount(templates: TransactionTemplate[], showHidden: boolean): number {
let count = 0;
for (let i = 0; i < templates.length; i++) {
if (showHidden || !templates[i].hidden) {
for (const template of templates) {
if (showHidden || !template.hidden) {
count++;
}
}
@@ -23,9 +24,9 @@ export function getAvailableTemplateCount(templates: TransactionTemplate[], show
}
export function getFirstShowingId(templates: TransactionTemplate[], showHidden: boolean): string | null {
for (let i = 0; i < templates.length; i++) {
if (showHidden || !templates[i].hidden) {
return templates[i].id;
for (const template of templates) {
if (showHidden || !template.hidden) {
return template.id;
}
}
@@ -33,9 +34,9 @@ export function getFirstShowingId(templates: TransactionTemplate[], showHidden:
}
export function getLastShowingId(templates: TransactionTemplate[], showHidden: boolean): string | null {
for (let i = templates.length - 1; i >= 0; i--) {
if (showHidden || !templates[i].hidden) {
return templates[i].id;
for (const template of reversed(templates)) {
if (showHidden || !template.hidden) {
return template.id;
}
}
+6 -7
View File
@@ -39,7 +39,7 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
}
if (!options.type && options.categoryId && options.categoryId !== '0' && allCategoriesMap[options.categoryId]) {
const category = allCategoriesMap[options.categoryId];
const category = allCategoriesMap[options.categoryId] as TransactionCategory;
const type = categoryTypeToTransactionType(category.type);
if (isNumber(type)) {
@@ -102,8 +102,8 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
if (allVisibleAccounts.length) {
if (options.accountId && options.accountId !== '0') {
for (let i = 0; i < allVisibleAccounts.length; i++) {
if (allVisibleAccounts[i].id === options.accountId) {
for (const account of allVisibleAccounts) {
if (account.id === options.accountId) {
transaction.sourceAccountId = options.accountId;
transaction.destinationAccountId = options.accountId;
break;
@@ -115,7 +115,7 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
if (defaultAccountId && allAccountsMap[defaultAccountId] && !allAccountsMap[defaultAccountId].hidden) {
transaction.sourceAccountId = defaultAccountId;
} else {
transaction.sourceAccountId = allVisibleAccounts[0].id;
transaction.sourceAccountId = allVisibleAccounts[0]!.id;
}
}
@@ -123,7 +123,7 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
if (defaultAccountId && allAccountsMap[defaultAccountId] && !allAccountsMap[defaultAccountId].hidden) {
transaction.destinationAccountId = defaultAccountId;
} else {
transaction.destinationAccountId = allVisibleAccounts[0].id;
transaction.destinationAccountId = allVisibleAccounts[0]!.id;
}
}
}
@@ -132,8 +132,7 @@ export function setTransactionModelByTransaction(transaction: Transaction, trans
const tagIds = options.tagIds.split(',');
const finalTagIds = [];
for (let i = 0; i < tagIds.length; i++) {
const tagId = tagIds[i];
for (const tagId of tagIds) {
const tag = allTagsMap[tagId];
if (tag && !tag.hidden) {