patch 9.0.0196: finding value in list may require a for loop

Problem:    Finding value in list may require a for loop.
Solution:   Add indexof(). (Yegappan Lakshmanan, closes #10903)
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index a65f60d..3c0f143 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -291,6 +291,8 @@
 indent({lnum})			Number	indent of line {lnum}
 index({object}, {expr} [, {start} [, {ic}]])
 				Number	index in {object} where {expr} appears
+indexof({object}, {expr} [, {opts}]])
+				Number	index in {object} where {expr} is true
 input({prompt} [, {text} [, {completion}]])
 				String	get input from the user
 inputdialog({prompt} [, {text} [, {cancelreturn}]])
@@ -4730,19 +4732,25 @@
 			GetLnum()->indent()
 
 index({object}, {expr} [, {start} [, {ic}]])			*index()*
+		Find {expr} in {object} and return its index.  See
+		|filterof()| for using a lambda to select the item.
+
 		If {object} is a |List| return the lowest index where the item
 		has a value equal to {expr}.  There is no automatic
 		conversion, so the String "4" is different from the Number 4.
 		And the number 4 is different from the Float 4.0.  The value
-		of 'ignorecase' is not used here, case always matters.
+		of 'ignorecase' is not used here, case matters as indicated by
+		the {ic} argument.
 
 		If {object} is |Blob| return the lowest index where the byte
 		value is equal to {expr}.
 
 		If {start} is given then start looking at the item with index
 		{start} (may be negative for an item relative to the end).
+
 		When {ic} is given and it is |TRUE|, ignore case.  Otherwise
 		case must match.
+
 		-1 is returned when {expr} is not found in {object}.
 		Example: >
 			:let idx = index(words, "the")
@@ -4751,6 +4759,44 @@
 <		Can also be used as a |method|: >
 			GetObject()->index(what)
 
+indexof({object}, {expr} [, {opt}])			*indexof()*
+		{object} must be a |List| or a |Blob|.
+		If {object} is a |List|, evaluate {expr} for each item in the
+		List until the expression returns v:true and return the index
+		of this item.
+
+		If {object} is a |Blob| evaluate {expr} for each byte in the
+		Blob until the expression returns v:true and return the index
+		of this byte.
+
+		{expr} must be a |string| or |Funcref|.
+
+		If {expr} is a |string|: If {object} is a |List|, inside
+		{expr} |v:key| has the index of the current List item and
+		|v:val| has the value of the item.  If {object} is a |Blob|,
+		inside {expr} |v:key| has the index of the current byte and
+		|v:val| has the byte value.
+
+		If {expr} is a |Funcref| it must take two arguments:
+			1. the key or the index of the current item.
+			2. the value of the current item.
+		The function must return |TRUE| if the item is found and the
+		search should stop.
+
+		The optional argument {opt} is a Dict and supports the
+		following items:
+		    start	start evaluating {expr} at the item with index
+				{start} (may be negative for an item relative
+				to the end).
+		Returns -1 when {expr} evaluates to v:false for all the items.
+		Example: >
+			:let l = [#{n: 10}, #{n: 20}, #{n: 30]]
+			:let idx = indexof(l, "v:val.n == 20")
+			:let idx = indexof(l, {i, v -> v.n == 30})
+
+<		Can also be used as a |method|: >
+			mylist->indexof(expr)
+
 input({prompt} [, {text} [, {completion}]])		*input()*
 		The result is a String, which is whatever the user typed on
 		the command-line.  The {prompt} argument is either a prompt