Tag "metadata" onto an array in ruby - ruby-on-rails

I have some code which assembles two-dimensional arrays to be sent to the Spreadsheet gem's excel-building methods. I'd like to "tag" some subarrays (corresponding to rows) with formatting codes like {:color => "red"}.
Can anyone see a way of doing this? I could achieve a similar result by storing a seperate object which has the formatting option and (for example) the indexes to all rows i want to apply that format to. But it would be nicer if I could stick it straight onto the row itself as i build my data.
One thing that occurred to me is to use some kind of namespaced hash as the last entry in an array, if i want to format it, and then strip that out again in the spreadsheet builder. But, this seems risky as it's then in the array's actual data. Is there any kind of instance variable or something i can tap into with an array to "shove" my metadata in there?
I'm using Rails 2.2 for this app, in case that's relevant.

Since each row contains data and possibly some metadata, it seems natural to represent all rows as an Array of Hashes, where each Hash contains a :data key and a :metadata key. The latter can be omitted or can just point to an empty Hash if you do not have any metadata for the row, whichever you prefer.
I have no experience with the Spreadsheet gem, but I assume it requires an Array of Arrays as input, which you can create in a straightforward manner from the Array of Hashes as shown in the code below.
rows = [
{
data: [2, 3, 5],
metadata: { color: 'red' }
},
{
data: [7, 11, 13],
metadata: {}
}
]
# Transform into Array of Arrays, removing all metadata
rows.map { |row| row[:data] }
# => [[2, 3, 5], [7, 11, 13]]

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]

In a Rails form, can select options be saved to the database as a hash?

Let's say I have the following select boxes in my form for a Gate object:
f.select(:type_use, options_for_select([['Enter & Exit', 8],
['Only Enter', 4],
['Only Exit', 4],
['Only Enter for visitors', 2],
['Only Exit for visitors', 2]],
#gate.type_use),
{ :include_blank => '- select -' },
{ :class => 'form-control'})
These options will never change. The integers like 4 and 8 represent the number of cycles per day, and I later use these integers to do calculations. However I still want to retain the correct string labels for each integer for use in my view, so i can show that a gate has an 'Only Exit' type of use, for example.
So, is it possible to save select options as a hash, or does Rails have some other way to map integers to strings for use in my application?
Previously what i've been doing is just saving the string values, and then using if statements, manually assigning to a variable the corresponding integer based on the string value, before doing calculations. But I have yet to discover a more efficient and elegant way to do this.
In my research I did find information about Enums, but I don't think it applies to this situation because I have duplicate integers and Enums seem more like sequential indexes to me. Also it seems that other questions about hashes in select boxes have revolved around populating options for select with a hash, rather than saving as a hash
You can save Hash and Array by using Serialize on the Model you want to save the Hash or Array
Ex:
class User < Active::Record
serialize :data, Hash # for hash
serialize :other_data, Array # for array
end
There is also a DataType called hstore in postgres that allows you to save Hash data and then be able to perform searches and index items in the Hash
To use it you first have to enable the hstore extension and then use it in your migrations
.... add_column :data_set, :hstore, default: {}

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