Merging two arrays of Capybara elements - arrays

This is similar to something I posted yesterday but i got mixed up with what I actually had in front of me. I have two arrays that need merging into the same index value but I have capybara elements as opposed to strings and integers.
Example
#returned_names = page.all('#results > table.result > tbody > tr.data:first-of-type > td')
#returned_yobs = page.all('#results > table.result > tbody > tr.data:nth-child(2) > td')
# Returns
#returned_names = [#<Capybara::Element tag="td">, #<Capybara::Element tag="td">, #<Capybara::Element tag="td">]
#returned_yobs = [#<Capybara::Element tag="td">, #<Capybara::Element tag="td">, #<Capybara::Element tag="td">]
So based on yesterday's answer to merge these together, matching index values I should do
#collection = #returned_names.zip(#returned_yobs).map { |r| r.join(' ') }
# Returns
["#<Capybara::Node::Element:0x000000038c50e8> #<Capybara::Node::Element:0x000000036fadf8>",
"#<Capybara::Node::Element:0x000000038c50c0> #<Capybara::Node::Element:0x000000036fadd0>",
"#<Capybara::Node::Element:0x000000038c5020> #<Capybara::Node::Element:0x000000036fada8>"]
Which so far looks like it's doing the right thing. I need to then convert this to an array of its text values, but when I do
#collection.map { |t| t.text }
I get an error
undefined method `text' for #<String:0x00000001938310>
I'm guessing I can't map from here as I don't have an enumerable object at this stage?
Is there a way to get #collection back to an enumerable object so that I can then map the text values ?

Array#join converts each object (i.e. node) to a string. This should work:
#returned_names.zip(#returned_yobs).map { |name, yob| "#{name.text} #{yob.text}" }

how about this:
#collection.each { |capybara_element| }.map(&:text)
or more verbose but would do the same thing:
#text_collection = []
#collection.each do |element|
#text_collection.push(element.text)
end

Related

Return object after performing intersection of two arrays based on attribute

I have two arrays, both filled with objects that have numerous attributes. Both arrays are holding the same object types. I want to find where objects match based on their attribute id
Object example:
#<Link:0x00007fac5eb6afc8 #id = 2002001, #length=40, #area='mars' ...>
Example arrays filled with objects:
array_links = [<Link:0x00007fac5eb6afc8>, <Link:0x00007fdf5eb7afc2>, <Link:0x000081dag6zb7agg8>... ]
selected_links = [<Link:0x00007fad8ob6gbh5>, <Link:0x00007fdg7hh4tif4>, <Link:0x000081dag7ij5bhh9>... ]
If these were strings of the object IDs and there was a match, I could use:
intersection = array_links & selected_links
However I want to do this based on their attribute and return a matching object itself.
Something like:
intersection = array_links.select(&:id) & selected_links.select(&:id)
But of course, not that, as that doesn't work, any ideas? :)
you can:
1 :
override the eql?(other) method then the array intersection will work
class Link < ApplicationRecord
def eql?(other)
self.class == other.class && self.id == other&.id # classes comparing class is a guard here
end
# you should always update the hash if you are overriding the eql?() https://stackoverflow.com/a/54961965/5872935
def hash
self.id.hash
end
end
2:
use array.select:
array_links.flat_map {|i| selected_links.select {|k| k.user_id == i.user_id }}
If they are the same object in memory, ie array_links = [<Link:0x123] and selected_links = [<Link:0x123>], then your solution of:
intersection = array_links & selected_links
Should work.
If they are not, you could loop over you array_links and select those which are in selected_links:
intersection = array_links.select do |link|
link.id.in? selected_links.map(&:id)
end
The result will be the same if you loop over selected_links and select those in array_links.
Depending on your resources and the size of these arrays, you could memoize selected_links.map(&:id) to prevent this from being re-built on each iteration.

Kotlin - Find matching objects in array

Let's say I have an array of strings and I want to get a list with objects that match, such as:
var locales=Locale.getAvailableLocales()
val filtered = locales.filter { l-> l.language=="en" }
except, instead of a single value I want to compare it with another list, like:
val lang = listOf("en", "fr", "es")
How do I do that? I'm looking for a one-liner solution without any loops. Thanks!
Like this
var locales = Locale.getAvailableLocales()
val filtered = locales.filter { l -> lang.contains(l.language)}
As pointed out in comments, you can skip naming the parameter to the lambda, and use it keyword to have either of the following:
val filtered1 = locales.filter{ lang.contains(it.language) }
val filtered2 = locales.filter{ it.language in lang }
Just remember to have a suitable data structure for the languages, so that the contains() method has low time complexity like a Set.

Ruby variable regular expression in Array Select

I'm trying to exclude elements from an array of strings using array.select. I have this method:
def filter_out_other_bad_vals(array_of_strs, things_i_want)
array_of_strs = array_of_strs.select { |line| /"#{things_i_want}"/.match(line) }
end
I want to pass a string as a variable things_i_want. But this does not return any matches:
array = ["want_this", "do_not_want", "do_not_want","want_this", "want_this"]
pattern = 'want_this'
array = filter_out_other_bad_vals(array, pattern)
This returns an empty array. But if I hardcode the value in the match expression, I get what I want.
def filter_out_other_bad_vals(array_of_strs, things_i_want)
array_of_strs = array_of_strs.select { |line| /want_this/.match(line) }
end
How do I put a variable in the regex? What am I doing wrong?
I could just traverse the array, check each item, and then save the value in another array, but that's not very ruby-like, is it?
You include quotes in regex definition:
/"#{things_i_want}"/
remove them and it should work:
/#{things_i_want}/
EDIT:
By the way, you don't have to use regex for exact matching, you can use equality check (==) or #include? depending if you need a string to be equal to thing you want or just include it:
> array = ["want_this", "do_not_want", "do_not_want","want_this", "want_this"]
> array.select{|line| line == 'want_this'}
# => ["want_this", "want_this", "want_this"]
> array.select{|line| line.include? 'want_this'}
# => ["want_this", "want_this", "want_this"]

How to search an array for values present in another array and output the indexes of values found into a new array in [mongodb]

I have a Collection in each document is an array field and I want to search it for the occurrence of elements that are in another array and output the indexes of elements that are found as an array.
For example:
I have a document with foo field,
{
foo = [1,4,3,6,6],
foo = [1,5,7,5,8],
foo = [2,4,3,1,6],
foo = [1,4,9,6,7]
}
and an array which contains the elements to be searched
bar = [3,6]
I want the output to be
{output = [2,3]}
{output = [-1,-1]}
{output = [2,4]}
{output = [-1,3]}
I have tried using aggregation pipeline and map function with $indexOfArray but can't seem to make it work.
You can use $map expression.
db.collection.aggregate([
{"$project":{
"output":{
"$map":{
"input":[3,6],
"in":{"$indexOfArray":["$foo","$$this"]}
}
}
}}
])

Scala Converting Each Array Element to String and Splitting

I have an array loaded in, and been playing around in the REPL but can't seem to get this to work.
My array looks like this:
record_id|string|FALSE|1|
offer_id|decimal|FALSE|1|1,1
decision_id|decimal|FALSE|1|1,1
offer_type_cd|integer|FALSE|1|1,1
promo_id|decimal|FALSE|1|1,1
pymt_method_type_cd|decimal|FALSE|1|1,1
cs_result_id|decimal|FALSE|1|1,1
cs_result_usage_type_cd|decimal|FALSE|1|1,1
rate_index_type_cd|decimal|FALSE|1|1,1
sub_product_id|decimal|FALSE|1|1,1
campaign_id|decimal|FALSE|1|1,1
When I run my command:
for(i <- 0 until schema.length){
val convert = schema(i).toString;
convert.split('|').drop(2);
println(convert);
}
It won't drop anything. It also is not splitting it on the |
Strings are immutable, and so split and drop don't mutate the string - they return a new one.
You need to capture the result in a new val
val split = convert.split('|').drop(2);
println(split.mkString(" "));
Consider also defining a lambda function for mapping each item in the array, where intermediate results are passed on with the function,
val res = schema.map(s => s.toString.split('|').drop(2))

Resources