yByX / y_by_x
rel.y_by_x(:value_attr, :key_attr)rel.yByX('valueAttr', 'keyAttr')Problem
Section titled “Problem”Create a lookup object/hash from a relation where one attribute becomes the key and another becomes the value.
Example: I want to create a mapping from product IDs to product names for quick lookups.
Description
Section titled “Description”This operator creates a Hash/object where keys come from one attribute and values from another. This is useful for creating lookup tables or dictionaries from relational data.
Parameters:
- First argument (
y) - The attribute to use as values - Second argument (
x) - The attribute to use as keys
The result is a plain Hash/object (not a relation).
Requirements
Section titled “Requirements”- Both specified attributes must exist in the relation
- The key attribute values should be unique (later values overwrite earlier ones for duplicate keys)
Examples
Section titled “Examples”Basic lookup table
Section titled “Basic lookup table”suppliers = Bmg::Relation.new([ { sid: "S1", name: "Smith", city: "London" }, { sid: "S2", name: "Jones", city: "Paris" }, { sid: "S3", name: "Blake", city: "Paris" },])
# Create a sid -> name mappingname_by_id = suppliers.y_by_x(:name, :sid)
# => { "S1" => "Smith", "S2" => "Jones", "S3" => "Blake" }
# Use for quick lookupsname_by_id["S1"] # => "Smith"const suppliers = Bmg([ { sid: "S1", name: "Smith", city: "London" }, { sid: "S2", name: "Jones", city: "Paris" }, { sid: "S3", name: "Blake", city: "Paris" },])
// Create a sid -> name mappingconst nameById = suppliers.yByX('name', 'sid')
// => { S1: "Smith", S2: "Jones", S3: "Blake" }
// Use for quick lookupsconsole.log(nameById['S1']) // => "Smith"Creating a price lookup
Section titled “Creating a price lookup”products = Bmg::Relation.new([ { sku: "WIDGET-01", name: "Widget", price: 9.99 }, { sku: "GADGET-02", name: "Gadget", price: 19.99 },])
price_by_sku = products.y_by_x(:price, :sku)
# => { "WIDGET-01" => 9.99, "GADGET-02" => 19.99 }const products = Bmg([ { sku: "WIDGET-01", name: "Widget", price: 9.99 }, { sku: "GADGET-02", name: "Gadget", price: 19.99 },])
const priceBySku = products.yByX('price', 'sku')
// => { "WIDGET-01": 9.99, "GADGET-02": 19.99 }Note on duplicates
Section titled “Note on duplicates”If multiple tuples have the same key value, later values will overwrite earlier ones:
data = Bmg::Relation.new([ { key: "A", value: 1 }, { key: "A", value: 2 }, # Overwrites previous])
data.y_by_x(:value, :key)# => { "A" => 2 } # Only one value is keptconst data = Bmg([ { key: "A", value: 1 }, { key: "A", value: 2 }, // Overwrites previous])
data.yByX('value', 'key')// => { A: 2 } // Only the last value is keptTo handle duplicates, consider using summarize with collect first.