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

Inherits:
Object
  • Object
show all
Includes:
MultivalPlusDelimDeprecatable, SepDeprecatable
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,
#   multival: true,
#   sep: ";"
xform = Explode::FieldValuesToNewRows.new(
  fields: %i[child parent],
  target: :val,
  multival: true,
  sep: ";"
)
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,
#   multival: true,
#   sep: ";",
#   keep_nil: true
xform = Explode::FieldValuesToNewRows.new(
  fields: %i[child parent],
  target: :val,
  multival: true,
  sep: ";",
  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

Methods included from SepDeprecatable

#usedelim

Methods included from MultivalPlusDelimDeprecatable

#set_multival

Constructor Details

#initialize(target:, fields: [], multival: omitted = true, sep: nil, 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

  • multival (Boolean) (defaults to: omitted = true)

    deprecated - do not use

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

    deprecated - do not use

  • 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



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

def initialize(target:, fields: [], multival: omitted = true,
  sep: nil, delim: nil, keep_nil: false,
  keep_empty: false)
  @fields = [fields].flatten
  @target = target
  @multival = if omitted && delim
    true
  else
    set_multival(multival, omitted, self)
  end
  if sep.nil? && delim.nil? && @multival && !omitted
    msg = "If you are expecting Kiba::Extend.delim to be used as "\
      "default `sep` value, please pass it as explicit `delim` "\
      "argument. In a future release of kiba-extend, the `delim` "\
      "value will no longer default to Kiba::Extend.delim."
    warn("#{Kiba::Extend.warning_label}:\n  #{self.class}: #{msg}")
    sep = Kiba::Extend.delim
  end
  @delim = usedelim(sepval: sep, delimval: delim, calledby: self,
    default: nil)
  @keep_nil = keep_nil
  @keep_empty = keep_empty
end

Instance Method Details

#process(row) ⇒ Object



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/kiba/extend/transforms/explode/field_values_to_new_rows.rb', line 249

def process(row, &)
  rows = []
  other_fields = row.keys - @fields
  other_data = {}
  other_fields.each { |f| other_data[f] = row.fetch(f, nil) }

  @fields.each do |field|
    val = row.fetch(field, nil)
    vals = if val.nil?
      [nil]
    elsif val.empty?
      [""]
    elsif @multival
      val.split(@delim, -1)
    else
      [val]
    end

    vals.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
  end
  rows.each(&)
  nil
end