Android Многострочное суммирование: запрос на сокращение кода - PullRequest
0 голосов
/ 29 марта 2020

У меня есть таблица с пятнадцатью строками. Каждая строка имеет три столбца и общий столбец. Я хочу получить общее количество по строке, общее количество и общее среднее.

Пользователь не может вводить данные для всех строк, и пользователь может пропустить строку.

Таким образом, код проверяет, ввел ли пользователь данные в одно из трех полей каждой строки.

  1. Если строка пуста, игнорируйте ее.
  2. Если некоторые поля заполнены, попросите пользователя заполнить оставшуюся часть строки.
  3. Если все поля в строке заполнены, суммируйте все ее поля и увеличьте делитель.

Я только для краткости вставил коды для строк 1 и 2, но это показывает суть чего я пытаюсь достичь:

Код:

var a1 = 0
var a2 = 0
var total = 0
var divider = 0


// Row 1
if (b1p1.text.isNotEmpty() or b2p1.text.isNotEmpty() or b3p1.text.isNotEmpty()) {
    var y = 0
    listOf(b1p1, b2p1, b3p1).forEach {
        if (it.text.isEmpty()) {
            it.error = "Fill up empty fields!"
            y = 1
        }
    }

    if (y == 0) {
        divider++
        listOf(b1p1, b2p1, b3p1).forEach {
            a1 += it.text.toString().toInt()
        }
        total1.text = a1.toString()
        total += a1
        e2 = 1
    } else {
        Toast.makeText(activity, "Error", Toast.LENGTH_SHORT).show()
    }
}

// Row 2
if (b1p2.text.isNotEmpty() or b2p2.text.isNotEmpty() or b3p2.text.isNotEmpty()) {
    var y = 0
    listOf(b1p2, b2p2, b3p2).forEach {
        if (it.text.isEmpty()) {
            it.error = "Fill up empty fields!"
            y = 1
        }
    }

    if (y == 0) {
        divider++
        listOf(b1p2, b2p2, b3p2).forEach {
            a2 += it.text.toString().toInt()
        }
        total2.text = a2.toString()
        total += a2
    } else {

        Toast.makeText(activity, "Error", Toast.LENGTH_SHORT).show()
    }
}

if (e2 == 1) {

    grandTotalTextView.text = total.toString()

    average = total.toDouble()/divider

    val decimalFormatter = DecimalFormat("#,###.##")

    averageTextView.text = decimalFormatter.format(average).toString()

    cyeSingleton.anct3b = decimalFormatter.format(average).toString()

} else {

    Toast.makeText(activity, "Error 2", Toast.LENGTH_SHORT).show()
}

Таблица:

Это лучшее, что я мог придумать. Если не будет другого предложения, я соглашусь на это.

Заранее спасибо!

** РЕДАКТИРОВАТЬ: Благодаря ** { ссылка }

data class TotalResult(val divider:Int, val allTotal:Int, val showError:Boolean)

private fun calculateTotalResult(allTextViews:List<List<TextView>>, totalTextViews:List<TextView>): TotalResult {
    var divider = 0
    var allTotal = 0
    var showError=false

    allTextViews.forEachIndexed{index, rowTextViews->
        val rowResult = calculateRowResult(rowTextViews as List<EditText>, totalTextViews[index])
        if(!rowResult.ignoreRow){
            if(rowResult.allFieldsFilled){
                divider+=1
                allTotal+=rowResult.rowTotal
            }else{
                showError = true
            }
        }
    }

    Toast.makeText(
        activity,
        "$divider, $allTotal, $showError", Toast.LENGTH_SHORT)
        .show()

    return TotalResult(divider, allTotal, showError)

}

data class RowResult(val ignoreRow:Boolean, val allFieldsFilled:Boolean, val rowTotal:Int)

private fun calculateRowResult(rowTextViews:List<EditText>, totalTextView:TextView): RowResult {
    val ignore = rowTextViews.filter{it.text.isBlank()}.count() == rowTextViews.size
    if(ignore)
        return RowResult(true, false, 0)

    var emptyFieldCount = 0
    var total = 0
    rowTextViews.forEach {textView ->
        if (textView.text.isEmpty()) {
            textView.error = "Fill up empty fields!"
            emptyFieldCount +=1
        }else{
            val fieldValue:Int? = textView.text.toString().toIntOrNull() // or toIntOrElse{0}
            if(fieldValue!=null) total+=fieldValue
        }
    }

    if(emptyFieldCount==0)
        totalTextView.text = total.toString()

    return RowResult(false, emptyFieldCount==0, total)
}

1 Ответ

1 голос
/ 29 марта 2020
fun main(){
  val totalResult = calculateTotalResult(
    allTextViews = listOf(
        listOf(t11,t12,t13),
        listOf(t21,t22,t23)
    ),
    totalTextViews = listOf(totalView1, totalView2)
  )

  // single Toast error
  if(totalResult.showError){
      // showToast(error)
  }

  // use totalResult.divider, totalResult.allTotal
}

data class TotalResult(val divider:Int, val allTotal:Int, val showError:Boolean)

fun calculateTotalResult(allTextViews:List<List<TextView>>, totalTextViews:List<TextView>){
  var divider = 0
  var allTotal = 0
  var showError=false

  allTextViews.forEachIndexed{index, rowTextViews->
      val rowResult = calculateRowResult(rowTextViews, totalTextViews[index])
      if(!rowResult.ignore){
        if(rowResult.allFieldsFilled){
            divider+=1
            allTotal+=rowResult.rowTotal
        }else{
            showError = true
        }
      }
  }

  return TotalResult(divider, allTotal, showError)
}

data class RowResult(val ignoreRow:Boolean, val allFieldsFilled:Boolean, val rowTotal:Int)

fun calculateRowResult(rowTextViews:List<TextView>, totalTextView:TextView): RowResult {
    val ignore = rowTextViews.filter{it.isBlank()}.count() == rowTextViews.size
    if(ignore)
      return RowResult(true, false, 0)

    var emptyFieldCount = 0
    var total = 0
    rowTextViews.forEach {textView ->
        if (textView.text.isEmpty()) {
            textView.error = "Fill up empty fields!"
            emptyFieldCount +=1
        }else{
            val fieldValue:Int? = textView.text.toString().toIntOrNull() // or toIntOrElse{0}
            if(fieldValue!=null) total+=fieldValue
        }
    }

    if(emptyFieldCount==0)
      totalTextView.text = total.toString()

    return RowResult(false, emptyFieldCount==0, total)
}

Извлечено calculateTotalResult() и calculateRowResult(), поэтому нескольким строкам и столбцам не нужно повторять один и тот же код.

calculateRowResult() обрабатывает синглетную строку TextViews. Мне пришлось дважды повторить rowTextViews, один для вычисления игнорирования, другой для отображения ошибки в TextView, если не игнорировать. Мы пока не показываем Toast Error.

calculateTotalResult() повторяется по всем строкам и получает общий результат. Мы показываем только одну ошибку Toast (если требуется) после этого шага.

Код является псевдокодом, не проверен.

...