我需要使函数返回列表长度(当然,没有标准的scala方法)
val a = 3 :: 4 :: 7 :: 9 :: Nil
var b = 0
var i = 0
def listLength[A](xs: List[A]): Int = {
if (xs(i) != null && i < xs.length)
b += 1
i += 1
listLength(a)
b
}
println(listLength(a))
对于此方法,我有一个错误:java.lang.IndexOutOfBoundsException:4
答案 0 :(得分:2)
此xs(i) != null
并没有您的想法。 List
可能包含一个null
元素,但它与列表结尾无关,因此仍应计数。
此i < xs.length
完全违背了不使用List
来计算.length
长度的目的。
这个(或类似的东西)可能就是您想要的。
def listLength[A](xs: List[A]): Int = xs match {
case Nil => 0
case _ :: tail => 1 + listLength(tail)
}
答案 1 :(得分:1)
您不能// Array declaration
var items = [Item]()
var tableData = [Item]()
public func documentPicker(_ controller: UIDocumentPickerViewController,didPickDocumentsAt urls: [URL]) {
// Here I am getting user selected file url and its name from iCloud.
// I skipped to paste here.
// User picked file data appending into items array
items.append(Item(url: bookurl, title: name))
// Assign items data to tableData
if let data = UserDefaults.standard.data(forKey:"items") {
do {
let itemsUser = try PropertyListDecoder().decode(Array<Item>.self, from: data)
tableData = itemsUser
} catch { print(error) }
}
}
// MARK - TABLE VIEW DELEGATIONS
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tableData.count
}
// TableView data-load
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
let item = tableData[indexPath.row]
cell.name_label.text = item.name
}
return cell
}
成为List.apply(notExisingIndex)
clearly exploding in case of non existing index。
apply
如果愿意,您可以做 def apply(n: Int): A = {
val rest = drop(n)
if (n < 0 || rest.isEmpty) throw new IndexOutOfBoundsException("" + n)
rest.head
}
甚至可以做更好的Try(List.apply(notExisingIndex))
,但这可能不是一个好方法。
我将使用“模式匹配”找到List.lift
,直到列表为length
。
Nil
答案 2 :(得分:1)
我将前面的两个答案结合起来:
def length[T](list: List[T]) = {
@tailrec
def loop(list: List[T], res: Int): Int = list match {
case Nil => res
case head :: tail => loop(tail, res+1)
}
loop(list, 0)
}
这是尾递归的,因此可以编译为一个简单的循环,但在外部函数签名中没有虚假的额外值。