Rail postgres array contains (<#) dont include nil - ruby-on-rails

I have a Matchups table that includes a field that is equipment_id and stores an array
I am trying to search the Matchups table to get any records that have an array where it contains specific equipment ids. For example:
So I am running:
search_equipment_ids = [1, 2, 3, 4, 5]
Matchup.where("equipment_id <# ARRAY[?]", search_equipment_ids)
The following are a few examples of arrays that are stored in the table in equipment_id and what the above query would result in
[1, 2] = True
[3, 5] = True
[1, 2, 3] = True
[1, 2, nil, 3] = False
How can get the search to ignore that there might be a nil included in the array. I am going to make a change to how the array is stored so from here on out there will be no nil values...but in the mean time I need to take these into account.
I am using: https://www.postgresql.org/docs/9.5/static/functions-array.html as a reference.
I dont want to use the && operator because the Matchups table is huge it will return to many results if just comparing if one equipment id is present. I want to only return if all the equipment_ids are contained (excluding any nils).
Thank you!

How about removing the nil values from the array? That's easy:
Matchup.where(..., equipment_ids.compact)

Related

subscript Array change coordinates

How can I change subscript coordinates in an Array of Arrays [[Int]] so that the way to address a cell would be table[column-letter][row-number], same as Excel, instead of current ios table[row-number][column-number] for a given table like:
var table = [[0, 1, 2, 3],
[1, 32, 44, 25],
[2, 12, 66, 43],
[3, 3, 4, 5]]
Today table[2][1] = 12, but I want table[C][1] = 44.
I need this change to adapt formulas from excel into my app without changing the coordinate system or the tables from an Excel.
I know there are subscript functions in Array class which may help, but I couldnĀ“t make it work so far.
Today table2 = 12, but I want tableC = 44.
Do you know what is [2][1] actually means you are telling the compiler,
i want the element in the array that has index of [2] and by adding another [1], you are telling it that you need the element that has index of [1] that its inside the result of [2].
its an Array of Arrays if you take another look at it empty would be something like this ,
[[],[],[]] // no matter what is the values inside indexing is always the same
with that pointed out now lets take a look on what are you trying to do.
[C][1] = 44
As you can now probably tell this is not valid because [C] is not a valid index as index accept only Integer Types.
So what can we try ?.
Well you can try dictionaries
Read about them here
With dictionary at some point you will be able to get a value like this
value = table["C"]?[1]
or take a look on this example.
var foo :[String:[Int]] = ["A":[1,2,3], "B":[1,2,3]]
let colm = foo["A"]?[0]
Edit another solution inspired by #Paulw11
using this "A".utf16.first! - 65 will return 0 index to use inside the Array so you can additionally say from A to Z
table = ["MyChar".utf16.first! - 65][2]

How can I delete certain indeces defined in an array from an other array in ruby

I have a method that iterates over an array, does a bunch of stuff under certain conditions and depending on these conditions I would ALSO like to delete some of the elements. In order to keep track of the indexes I like to delete I converted the each in to an each_with_index loop and store the index of the elements that I like to delete in an array index_array. How can I delete exactly the items on those indexes in my original array? Looping over the index_array and using delete_at would change the original index. Please see below description of the scenario:
> my_array = [0,1,2,3,4,5,6,7]
> delete_these_indexes = [1,2,5]
the desired result is:
> my_array => [0,3,4,6,7,8]
How about this?
my_array = [0, 1, 2, 3, 4, 5, 6, 7]
delete_these_indices = [1, 2, 5]
delete_these_indices.sort.reverse_each {|i| my_array.delete_at(i) }
p my_array
# => [0, 3, 4, 6, 7, 8]
It's important to delete from the end of the array, since deleting an item will change the indices of all subsequent items, ergo sort.reverse_each. If you know the array is already sorted, you can just do reverse_each.
If you don't care bout modifying the delete_these_indices array, you can be somewhat more terse:
delete_these_indices.sort!
my_array.delete_at(i) while (i = delete_these_indices.pop)
Again, you can skip sort! if you know delete_these_indices is already sorted.
keep_these_indexes = my_array.each_index.to_a - delete_these_indexes
#=> [0, 3, 4, 6, 7]
If you wish to modify my_array (which appears to be the case):
my_array.replace(my_array.values_at(*keep_these_indexes))
#=> [0, 3, 4, 6, 7]
If not:
new_array = my_array.values_at(*keep_these_indexes)
See Array#values_at.
delete_these_indexes.each_with_index do |val, i|
my_array.delete_at(val - i)
end
deletes at the desired index taking into account how many have previously been deleted and adjusting for that
https://repl.it/CeHZ
Probably not the best answer, but you can do this as well:
delete_at_indices.each {|ind| my_array[ind] = nil }
my_array.delete(nil)
Takes a first pass to conceptually invalidate the data at the specified indices, then the call to .delete will blow out any values that match what's passed in.
This solution assumes that you can define a value that isn't valid for your array. Using nil will be problematic if you're treating this as a sparsely populated array (where nil is a valid value)
Technically you're iterating through each array once, but that Gentleman's Agreement on what your deletable value might make some people uncomfortable

Get documents by querying over an array

I have an array of ids. Now I want to get all the documents corresponding to the ids inside that array from a collection.
Is there any command by which I can achieve this?
I don't want to run a loop over that array and query for every element of the array.
Assume the array is
id = [1,2,3,4]
The collection is Scores, which has the field id among other fields.
I'm looking for something like Scores.find(..)
In ActiveRecord, the following query works as expected
Scores.find([1, 2, 3, 4])
Depending on the MongoDB adapter you use, it may work as well. According to this documentation, the same syntax is also supported in Mongoid.
Otherwise, you can generally use
Scores.where(id: [1, 2, 3, 4])
that will return a collection of records matching the given IDs.

Neo4j gem - Querying multiple parameters in one property

I'm not even sure if this title is the best description.
I'm building some basic filtering capabilities via a form for my events. Events have a category from a select drop down.
Now when you want to filter, you can select via checkboxes the categories you want to display.
I'm a bit stumped how to do that. Is it possible to do it all in one query? Or do you separate it into 1 for each category?
My old query was this current_user.friends.events(:event, :rel).where("rel.admin = {admin_p} AND event.detail = {detail_p}").params(admin_p: true, detail_p: true).pluck(:event)
In this case, I would need something like event.category = category1, category2, cateogry3 . Obviously this isn't how it's written. Ways to achieve this?
In cypher, IN lets you match results within an array.
MATCH (u:User)-[r1:INVITED_TO]->(e:Event) WHERE e.uuid IN [1, 2, 3, 4, 5] RETURN e
That would match events with any of the uuid properties in that array. In the Ruby gem, this is handled automatically for you in QueryProxy if you use an array in a where method.
current_user.events.where(category: [1, 2, 3, 4, 5])
In your form, ensure that each checkbox's value corresponds with its ID. Put those IDs into an array and search as demonstrated above.

Removing a "subset" from an array in Ruby

I want to remove some elements from an array contained in another array.
The way to do this in Java is:
myArray.removeAll(anotherArray)
This code removes the elements contained in anotherArray from myArray.
Is there something like removing the elements contained in myArray INTERSECTION anotherArray from myArray?
Yes, this is what the - operator (really Array#- method) is for:
a = [1, 2]
b = [2]
a - b
# => [1]
Use "Array Difference"
There's more than one way to do this in Ruby, but the most common is to call the array difference method Array#-. The documentation for this method says:
Returns a new array that is a copy of the original array, removing any items that also appear in other_ary. The order is preserved from the original array.
It compares elements using their hash and eql? methods for efficiency.
[ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
If you need set-like behavior, see the library class Set.
The minus sign looks like an operator, but is actually a method call on the first Array object. Obviously, you could also look at Set#difference if you're working with Set objects rather than an Array.

Resources