【问题标题】:Extracting transaction data from variable length arrays从可变长度数组中提取交易数据
【发布时间】:2019-07-31 06:08:09
【问题描述】:

我用 ruby​​ 构建了一个小程序,它从我自己的 PDF 银行对账单中收集表格数据。这是通过扫描每个 PDF 语句中的表格然后过滤掉交易行项目模式来实现的。

一切都很好,我已经设法收集了一个行项目数组作为字符串数组的数组。获取一个键控对象数组会更好,但语句格式有点棘手。

问题在于订单项的长度不同,因此始终知道要映射的正确值的位置有点棘手。

例如:

  1. ["Transaction 1", "1.00"]
  2. ["Transaction 2", "Hello World", "3.00"]
  3. ["Transaction 3", "Hello World", "feeffe", "5.00"]
  4. ["Transaction 4", "Hello World", "feeffe", "5.00", "12.00"]
  5. ["Transaction 5", "Hello World @ 10.00", "feeffe", "10.00", "12.00"]

订单项通常仅在 2 到 5 个数组项之间。

是否有一种有效/准确的方法可以将上述内容映射到:

  1. { description: "Transaction 1", amt: "1.00"}
  2. { description: "Transaction 2 - Hello World", amt: "3.00"}
  3. { description: "Transaction 3 - Hello World - feeffe", amt: "5.00"}
  4. { description: "Transaction 4 - Hello World - feeffe", amt: "5.00"}
  5. { description: "Transaction 5 - Hello World @ 10.00 - feeffe", amt: "10.00"}

-或者是编写查看数组长度并做出“最佳猜测”努力的 IF 条件的唯一方法?

【问题讨论】:

  • 您是否得到长度为 4 的行数组,其中包含实际值和费用值?或者这两个值只存在于长度为 5 的数组中。
  • 自从我和其他人发布了他们的答案后,您大大改变了问题。这是 SO 的禁忌,原因应该很明显。
  • 我只添加了 2 个示例 @CarySwoveland。没有改变问题。
  • #4 和#5 的最后一个元素将被忽略。 #1、#2 或 #3 的情况并非如此。如果您没有更改问题,为什么我的答案对#1、#2 和#3 给出了正确的结果,但对#4 和#5 却没有?为什么@ray 觉得需要他的“更新”?

标签: ruby-on-rails arrays ruby data-science


【解决方案1】:

如果你有,

row = ["Transaction 2", "Hello World", "3.00"]

你可以跟着做,

{ description: row[0..-2].join(' - '), amt: row[-1] }

您必须进一步控制这些行的迭代方式,以便进一步的逻辑会有所不同。

更新:

对于稍后指定的条件更新,可以看到行的长度可以为 5,其中实际数量是倒数第二个值。

data = (row.length == 5) ? [row[0..-3], row[-2]] : [row[0..-2], row[-1]]
{ description: data[0].join(' - '), amt: data[1] }

【讨论】:

  • 谢谢。这也是我的第一个想法。有一些异常值,其中数组以两个作为交易值的数组元素结尾。在这些情况下,倒数第二个是实际值,最后一个是费用值。我想我可以对每个数组进行计数以检查然后相应地更新索引值,我只是希望有一种更智能的方式,比如某种正则表达式等。
  • @HermannHH 您能否详细说明示例行,以便我更好地查看。
  • 我在我的问题中添加了示例 4 和 5。这些绝对是异常值,但它们确实出现了。
  • @HermannHH 我已经更新了答案。当然,您需要像我上面所做的那样定义边界。希望有更好的方法,否则我想念这里的东西。
【解决方案2】:

假设您的交易在变量tr 上,即

 tr=["Transaction 5", "Hello World", "feeffe", "10.00", "12.00"]

我会先把它分成那些看起来像数量的字符串和那些看起来不像的字符串:

amounts,texts= tr.partition {|el| /^\d+[.]\d{2}/ =~ el}

这里你可以检查!amounts.empty?,以防止无金额交易。现在你的哈希可能是

{
  transaction_name: texts.first,
  transaction_text: "#{texts[1]}#{amounts.size > 1 ? %( @ #{amounts.first}) : ''}#{texts.size > 2 ? %( - #{texts.last}) : ''}",
  amt: amounts.last
}

【讨论】:

  • 这正是我所希望的。它比手动映射值更动态且更智能。非常感谢!
【解决方案3】:

试试这个正则表达式:

"\K[^",\]]+

Here is Demo

【讨论】:

  • 谢谢。这似乎只匹配数组中的每个项目,因此对于这个问题并不真正适用,即它不区分不同类型/长度的行项目。感谢您的回答
【解决方案4】:

如果项目的数量总是决定数量元素的索引,你可以这样做:

input = [
  ["Transaction 1", "1.00"],
  ["Transaction 2", "Hello World", "3.00"],
  ["Transaction 3", "Hello World", "feeffe", "5.00"],
  ["Transaction 4", "Hello World", "feeffe", "5.00", "12.00"],
  ["Transaction 5", "Hello World @ 10.00", "feeffe", "10.00", "12.00"]
]

ROW_LENGTH_TO_AMOUNT_INDEX = {
  2 => 1,
  3 => 2,
  4 => 3,
  5 => 3,
}


def map(transactions)
  transactions.map do |row|
    amount_index = ROW_LENGTH_TO_AMOUNT_INDEX[row.length]
    {
      description: row[0],
      amt: row[amount_index]
    }
  end
end


p map(input)

[{:description=>"Transaction 1", :amt=>"1.00"}, {:description=>"Transaction 2", :amt=>"3.00"}, {:description=>"Transaction 3", :amt=>"5.00"}, {:description=>"Transaction 4", :amt=>"5.00"}, {:description=>"Transaction 5", :amt=>"10.00"}]

或者,也许是这样的?

MAPPERS = {
  2 => lambda { |row| { description: row[0], amt: row[1]} },
  3 => lambda { |row| { description: row[0], amt: row[2]} },
  4 => lambda { |row| { description: row[0], amt: row[3]} },
  5 => lambda { |row| { description: row[0], amt: row[3]} }
}


def map(transactions)
  transactions.map do |row|
    MAPPERS[row.length].call(row)
  end
end

【讨论】:

    【解决方案5】:
    arr = [["Transaction 1", "1.00"],
           ["Transaction 2", "Hello World", "3.00"],
           ["Transaction 3", "Hello World", "feeffe", "5.00"]]
    
    arr.map {|*first, last| { description: first.join(' - '), amt: last } }
      #=> [{:description=>"Transaction 1", :amt=>"1.00"},
      #    {:description=>"Transaction 2 - Hello World", :amt=>"3.00"},
      #    {:description=>"Transaction 3 - Hello World - feeffe", :amt=>"5.00"}]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-24
      • 2018-05-06
      • 1970-01-01
      • 2020-11-20
      • 2012-08-25
      相关资源
      最近更新 更多