In a vector with a) unique elements b) non unique ones
how does one find a single element?
Should I use filter and then get the 1st element from a result? Is there a more idiomatic way?
update 1
I haven't been able to make this compile:
let elems = create_btree_map_data(); //BTreeMap<i32, MyStruct>
//let elem = elems.iter().find(&&|k, v| v.status == Status::Good);
//let elem = elems.iter().find(|&k, &v| v.status == Status::Good);
//let elem = elems.iter().find(|&&k, &&v| v.status == Status::Good);
//let elem = elems.iter().find(&|k, v| v.status == Status::Good);
That is, I haven't been able to complitely dereference v to be able to apply a predicte to it.
Related
I have a list like List = ["google","facebook","instagram"] and a string P1 = "https://www.google.co.in/webhp?pws=0&gl=us&gws_rd=cr".
Now I need to find which element of List is present inside the P1.
For this I implemented below recursive function, but it returns ok as final value, is there a way that when (in this case) google is found, then H is returned and terminate the other recursive calls in stack.
I want this function to return google.
traverse_list([],P1)-> ok;
traverse_list([H|T],P1) ->
Pos=string:str(P1,H),
if Pos > 1 ->
io:fwrite("Bool inside no match is ~p~n",[Pos]),
io:fwrite("inside bool nomathc, ~p~n",[H]),
H;
true->
io:fwrite("value found :: ~p~n",[Pos])
end,
traverse_list(T,P1).
It returns ok because the stop condition of your recursion loop does it:
traverse_list([],P1)-> ok;
For this you should use lists:filter/2 or a list comprehension:
List = ["google","facebook","instagram"],
P1 = "https://www.google.co.in/webhp?pws=0&gl=us&gws_rd=cr",
lists:filter(fun(X) -> string:str(P1,X) > 1 end,List),
% or
[X || X <- List, string:str(P1,X) > 1],
Another Scala newbie question since I am not getting how to achieve this in a functional way (mostly coming from a scripting language background):
I have a list of strings:
val food-list = List("banana-name", "orange-name", "orange-num", "orange-name", "orange-num", "grape-name")
and where they are duplicated, I'd like to add an incrementing number into the string and get that in a list similar to the input list, like so:
List("banana-name", "orange1-name", "orange1-num", "orange2-name", "orange2-num", "grape-name")
I've grouped them up to get counts for them with:
val freqs = list.groupBy(identity).mapValues(v => List.range(1, v.length + 1))
Which gives me:
Map(orange-num -> List(1, 2), banana-name -> List(1), grape-name -> List(1), orange-name -> List(1, 2))
The order of the list is important (it should be in the original order of food-list) so I know it's problematic for me to use a Map at this point. The closest I feel I have gotten to a solution is:
food-list.map{l =>
if (freqs(l).length > 1){
freqs(l).map(n =>
l.split("-")(0) + n.toString + "-" + l.split("-")(1))
} else {
l
}
}
This of course gives me a wonky output since I am mapping the list of frequencies from the words value in freqs
List(banana-name, List(orange1-name, orange2-name), List(orange1-num, orange2-num), List(orange1-name, orange2-name), List(orange1-num, orange2-num), grape-name)
How is this done in a Scala fp way without resorting to clumsy for loops and counters?
If the indices are important, sometimes it's best to keep track of them explicitly using zipWithIndex (very similar to Python's enumerate):
food-list.zipWithIndex.groupBy(_._1).values.toList.flatMap{
//if only one entry in this group, don't change the values
//x is actually a tuple, could write case (str, idx) :: Nil => (str, idx) :: Nil
case x :: Nil => x :: Nil
//case where there are duplicate strings
case xs => xs.zipWithIndex.map {
//idx is index in the original list, n is index in the new list i.e. count
case ((str, idx), n) =>
//destructuring assignment, like python's (fruit, suffix) = ...
val Array(fruit, suffix) = str.split("-")
//string interpolation, returning a tuple
(s"$fruit${n+1}-$suffix", idx)
}
//We now have our list of (string, index) pairs;
//sort them and map to a list of just strings
}.sortBy(_._2).map(_._1)
Efficient and simple:
val food = List("banana-name", "orange-name", "orange-num",
"orange-name", "orange-num", "grape-name")
def replaceName(s: String, n: Int) = {
val tokens = s.split("-")
tokens(0) + n + "-" + tokens(1)
}
val indicesMap = scala.collection.mutable.HashMap.empty[String, Int]
val res = food.map { name =>
{
val n = indicesMap.getOrElse(name, 1)
indicesMap += (name -> (n + 1))
replaceName(name, n)
}
}
Here is an attempt to provide what you expected with foldLeft:
foodList.foldLeft((List[String](), Map[String, Int]()))//initial value
((a/*accumulator, list, map*/, v/*value from the list*/)=>
if (a._2.isDefinedAt(v))//already seen
(s"$v+${a._2(v)}" :: a._1, a._2.updated(v, a._2(v) + 1))
else
(v::a._1, a._2.updated(v, 1)))
._1/*select the list*/.reverse/*because we created in the opposite order*/
I have a string[] list and I wish to group the 5th element in the string array of all the list..
I found two different ways in doing this
let rec Publication x y (z:string [] list) =
if x < z.Length then
let muro = [z.[x].[y]]
let rest = Publication (x+1) y z
List.append muro rest
else []
where z is the string[] list and y is the element that I wish to list.
and
let Publication x (z:string [] list) = [for i in 0 .. (z.Length-1) -> z.[i].[x]]
In the first case, I get a stack overflow error when working with a large set of data and the second one takes to long. Can anyone help me find a third and more eficient way? thanks!
Your second version seems sensible on the surface, but I wonder if the problem is not the indexed access to z, as the list is iterated from the head for each z.[i] call. What I would try is plain and simple:
let publication idx (lst: string [] list) =
lst |> List.map (fun arr -> arr.[idx])
You have a list of arrays and an index, you go through the list and get element by the index from each array.
First of all im VERY VERY noob in f# so I need your help :)
I have a library with 50 lists that each have around 10 entries
What I need to do is join all 50 lists into one big list. The things is that I cant use "for" or mutable variables.
what I have done (which I think is horribly done) is:
let rec finalList x =
if x < wallID.Length then List.append [interfaz.hola(wallID.Item(x)).[0].[1]] [finalList]
else listaFinal (x+1)
printfn "list %A" (listaFinal 10 )
WallID represents one of the 50 lists and interfaz.GetMuroHumano(wallID.Item(x)).[0].[1] gets me one of the entries that I need. (for now if a can just get one of the data for each wallID im ok)
again im verrrrry noob and I hope you guys can help me
thanks
EDIT:
So now its partially working..
let rec finalList x y =
if x < wallID.Length then
if y < [interfaz.GetMuroHumano(wallID.Item(x)).[y]].Length then
let current = [interfaz.GetMuroHumano(wallID.Item(x)).[y].[1]]
let rest = finalList (x y+1)
List.append current rest
else finalList (x+1 y)
else []
vut im getting errors calling the function finalList it says that "y" is not an int but a string
It is hard to say what is wrong with your code without seeing a complete version. As Daniel points out, there is a built-in library function for doing that - in fact, you do not even need List.collect, because there is List.concat that takes a list of lists.
However, you might still try to get your original code to work - this is useful for understanding functional concepts! I added some comments that can help you understand how it should work:
let rec finalList x =
if x < wallIDLength then
// Get the list at the index 'x'
let current = interfaz.GetMuroHumano(wallID.Item(x))
// Recursively process the rest of the lists
let rest = finalList (x + 1)
// Check that both 'current' and 'rest' are variables
// of type list<'T> where 'T is the element type
List.append current rest
else
// Return empty list if we got too far
[]
// Start from the first index: 0
printfn "list %A" (finalList 0)
let flatten xs = List.collect id xs
I have list of Objects(Name A), A have property B and C. I need to find the object in the list which B property equal with another object's C property. For Example:
def objectList = [A1,A2,A3,A4,A5,A6,A7,A8];
if A1.B == A2.C then return A1,A2;
Any good way to do that?
You can use the findAll method for this:
def list = []
def matching = list.findAll { A a ->
a.B == a.C
}
Update
You can get all the pairs of matching objects this way:
def matching = []
list.unique { A a1, A a2 ->
if (a1.B == a2.C || a1.C == a2.B) {
matching << a1 << a2
}
return 1
}
This is kind of a hacky solution since it does not use the unique method as intended.
Not sure whether you want your result flattened or not, anyway here's a solution returning a list of tuples:
def result = list.inject([]) {acc,a1->
list.each {a2->
if (!a1.is(a2) && a1.b == a2.c) {
acc << [a1,a2]
}
}
acc
}