Class: Kiba::Extend::Transforms::Explode::FieldValuesToNewRows

Inherits:
Object
  • Object
show all
Defined in:
lib/kiba/extend/transforms/explode/field_values_to_new_rows.rb

Overview

Examples:

Multival, without keeping nil or empty

# Used in pipeline as:
# transform Explode::FieldValuesToNewRows,
#   fields: %i[child parent],
#   target: :val,
#   delim: ";"
xform = Explode::FieldValuesToNewRows.new(
  fields: %i[child parent],
  target: :val,
  delim: ";"
)
input = [
  {id: 1, child: "a;b", parent: "c;d"},
  {id: 2, child: "a", parent: "b"},
  {id: 3, child: "", parent: "q"},
  {id: 4, child: "n", parent: nil},
  {id: 5, child: "", parent: nil},
  {id: 6, child: "p;", parent: ";z"},
  {id: 7, child: "m;;n", parent: "s"}
]
result = Kiba::StreamingRunner.transform_stream(input, xform)
  .map{ |row| row }
expected = [
  {id: 1, val: "a"},
  {id: 1, val: "b"},
  {id: 1, val: "c"},
  {id: 1, val: "d"},
  {id: 2, val: "a"},
  {id: 2, val: "b"},
  {id: 3, val: "q"},
  {id: 4, val: "n"},
  {id: 6, val: "p"},
  {id: 6, val: "z"},
  {id: 7, val: "m"},
  {id: 7, val: "n"},
  {id: 7, val: "s"}
]
expect(result).to eq(expected)

Multival, keeping nil

# Used in pipeline as:
# transform Explode::FieldValuesToNewRows,
#   fields: %i[child parent],
#   target: :val,
#   delim: ";",
#   keep_nil: true
xform = Explode::FieldValuesToNewRows.new(
  fields: %i[child parent],
  target: :val,
  delim: ";",
  keep_nil: true
)
input = [
  {id: 1, child: "a;b", parent: "c;d"},
  {id: 2, child: "a", parent: "b"},
  {id: 3, child: "", parent: "q"},
  {id: 4, child: "n", parent: nil},
  {id: 5, child: "", parent: nil},
  {id: 6, child: "p;", parent: ";z"},
  {id: 7, child: "m;;n", parent: "s"}
]
result = Kiba::StreamingRunner.transform_stream(input, xform)
  .map{ |row| row }
expected = [
  {id: 1, val: "a"},
  {id: 1, val: "b"},
  {id: 1, val: "c"},
  {id: 1, val: "d"},
  {id: 2, val: "a"},
  {id: 2, val: "b"},
  {id: 3, val: "q"},
  {id: 4, val: "n"},
  {id: 4, val: nil},
  {id: 5, val: nil},
  {id: 6, val: "p"},
  {id: 6, val: "z"},
  {id: 7, val: "m"},
  {id: 7, val: "n"},
  {id: 7, val: "s"}
]
expect(result).to eq(expected)

Multival (via delim param only), keeping empty

# Used in pipeline as:
# transform Explode::FieldValuesToNewRows,
#   fields: %i[child parent],
#   target: :val,
#   delim: ";",
#   keep_empty: true
xform = Explode::FieldValuesToNewRows.new(
  fields: %i[child parent],
  target: :val,
  delim: ";",
  keep_empty: true
)
input = [
  {id: 1, child: "a;b", parent: "c;d"},
  {id: 2, child: "a", parent: "b"},
  {id: 3, child: "", parent: "q"},
  {id: 4, child: "n", parent: nil},
  {id: 5, child: "", parent: nil},
  {id: 6, child: "p;", parent: ";z"},
  {id: 7, child: "m;;n", parent: "s"}
]
result = Kiba::StreamingRunner.transform_stream(input, xform)
  .map{ |row| row }
expected = [
  {id: 1, val: "a"},
  {id: 1, val: "b"},
  {id: 1, val: "c"},
  {id: 1, val: "d"},
  {id: 2, val: "a"},
  {id: 2, val: "b"},
  {id: 3, val: ""},
  {id: 3, val: "q"},
  {id: 4, val: "n"},
  {id: 5, val: ""},
  {id: 6, val: "p"},
  {id: 6, val: ""},
  {id: 6, val: ""},
  {id: 6, val: "z"},
  {id: 7, val: "m"},
  {id: 7, val: ""},
  {id: 7, val: "n"},
  {id: 7, val: "s"}
]
expect(result).to eq(expected)

Single val, without keeping nil or empty

# Used in pipeline as:
# transform Explode::FieldValuesToNewRows,
#   fields: %i[child parent],
#   target: :val,
xform = Explode::FieldValuesToNewRows.new(
  fields: %i[child parent],
  target: :val,
)
input = [
  {id: 1, child: "a;b", parent: "c;d"},
  {id: 2, child: "a", parent: "b"},
  {id: 3, child: "", parent: "q"},
  {id: 4, child: "n", parent: nil},
  {id: 5, child: "", parent: nil},
  {id: 6, child: "p;", parent: ";z"},
  {id: 7, child: "m;;n", parent: "s"}
]
result = Kiba::StreamingRunner.transform_stream(input, xform)
  .map{ |row| row }
expected = [
  {id: 1, val: "a;b"},
  {id: 1, val: "c;d"},
  {id: 2, val: "a"},
  {id: 2, val: "b"},
  {id: 3, val: "q"},
  {id: 4, val: "n"},
  {id: 6, val: "p;"},
  {id: 6, val: ";z"},
  {id: 7, val: "m;;n"},
  {id: 7, val: "s"}
]
expect(result).to eq(expected)

Single val, keeping nil and empty

# Used in pipeline as:
# transform Explode::FieldValuesToNewRows,
#   fields: %i[child parent],
#   target: :val,
#   keep_nil: true,
#   keep_empty: true
xform = Explode::FieldValuesToNewRows.new(
  fields: %i[child parent],
  target: :val,
  keep_nil: true,
  keep_empty: true
)
input = [
  {id: 1, child: "a;b", parent: "c;d"},
  {id: 2, child: "a", parent: "b"},
  {id: 3, child: "", parent: "q"},
  {id: 4, child: "n", parent: nil},
  {id: 5, child: "", parent: nil},
  {id: 6, child: "p;", parent: ";z"},
  {id: 7, child: "m;;n", parent: "s"}
]
result = Kiba::StreamingRunner.transform_stream(input, xform)
  .map{ |row| row }
expected = [
  {id: 1, val: "a;b"},
  {id: 1, val: "c;d"},
  {id: 2, val: "a"},
  {id: 2, val: "b"},
  {id: 3, val: ""},
  {id: 3, val: "q"},
  {id: 4, val: "n"},
  {id: 4, val: nil},
  {id: 5, val: ""},
  {id: 5, val: nil},
  {id: 6, val: "p;"},
  {id: 6, val: ";z"},
  {id: 7, val: "m;;n"},
  {id: 7, val: "s"}
]
expect(result).to eq(expected)

Instance Method Summary collapse

Constructor Details

#initialize(target:, fields: [], delim: nil, keep_nil: false, keep_empty: false) ⇒ FieldValuesToNewRows

Returns a new instance of FieldValuesToNewRows.

Parameters:

  • target (Symbol)

    new field into which existing field values will be mapped

  • fields (Symbol, Array<Symbol>) (defaults to: [])

    from which values will be exploded

  • delim (nil, String) (defaults to: nil)

    used to split field values

  • keep_nil (Boolean) (defaults to: false)

    whether to create an exploded row for a Nil value

  • keep_empty (Boolean) (defaults to: false)

    whether to create an exploded row for a empty value



216
217
218
219
220
221
222
223
# File 'lib/kiba/extend/transforms/explode/field_values_to_new_rows.rb', line 216

def initialize(target:, fields: [], delim: nil, keep_nil: false,
  keep_empty: false)
  @target = target
  @fields = [fields].flatten
  @delim = delim
  @keep_nil = keep_nil
  @keep_empty = keep_empty
end

Instance Method Details

#process(row) ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/kiba/extend/transforms/explode/field_values_to_new_rows.rb', line 225

def process(row, &)
  rows = []
  other_data = row.clone
  fields.each { |field| other_data.delete(field) }

  fields.map { |field| split_field_val(row, field) }
    .flatten
    .each do |val|
      next if !keep_nil && val.nil?
      next if !(val.nil? || keep_empty) && val.empty?

      new_row = other_data.clone
      new_row[target] = val
      rows << new_row
    end

  rows.each(&)
  nil
end