Следующий код работает хорошо.
const handleInputChange = function (e) {
const formatValue = function () {
// Remove non-digit, except '.' and remove everything beginning from second decimal '.'
return e.target.value.replace(/[^0-9.]|(?<=^[^.]*\.[^.]*)\..*/g, '');
};
if (formatValue()) {
if (fieldSuffix === 'Percentage') {
// Percentage decimal truncated
const truncatedPercentage = formatValue().replace(/\..*/, '');
if (e.nativeEvent.inputType === 'deleteContentBackward') return setVal(`${formatValue()}%`.replace(/^\d%$|(\d|\.)(?=%)/, ''));
return setVal(`${truncatedPercentage}%`);
}
if (fieldSuffix === 'Dollars') {
// Truncated to two decimal places, not rounded
const truncatedDollar = formatValue().replace(/(?<=\.\d{2}).*/, '');
// Format and insert ','
return setVal(`$ ${truncatedDollar}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','));
}
}
return setVal('');
};
Я все еще чувствую, что в этом коде много избыточных и необработанных случаев
То, что упустили другие: если вы хотите, чтобы это было только между элементами, а не спереди или сзади, вам нужно выполнить дополнительную проверку:
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T element)
{
bool first = true;
foreach (T value in source)
{
if (!first) yield return element;
yield return value;
first = false;
}
}
I Вы кодировали ленивое решение в духе решений Linq! Другие решения, которые я придумал, включали обход всего списка перед возвратом данных, а затем возвращение полученного списка.
Некоторые из других ответов имеют проверку if на каждой итерации цикла.
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T element)
{
using (var enumerator = source.GetEnumerator()) {
if (enumerator.MoveNext()) {
yield return enumerator.Current;
while (enumerator.MoveNext()) {
yield return element;
yield return enumerator.Current;
}
}
}
}
Если вам интересно, как это реализовать, я бы сделал так:
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> collection, T value)
{
foreach(T item in collection)
{
yield return item;
yield return value;
}
yield break;
}
Было бы довольно просто написать:
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T value) {
bool first = true;
foreach(T item in source) {
if(first) { first = false; }
else { yield return value; }
yield return item;
}
}