【问题标题】:Converting PHP array manipulation to Ruby hashes将 PHP 数组操作转换为 Ruby 哈希
【发布时间】:2015-01-25 03:35:17
【问题描述】:

我已经编写了这个脚本以在 PHP 中运行,并且正在尝试将其转换为 Ruby。

代码:

$cases = array();


foreach($results as $result)
{
    if(!array_key_exists($result['id'], $cases))
        $cases[$result['id']] = array($result);
    else
        $cases[$result['id']][] = $result;
}

foreach($cases as $key => $case)
{
    foreach($case as $payment)
    {
        if(count($case) > 1)
        {

            $cases[$key]['total'] += ($payment['p1'] > $payment['p2']) ? $payment['p1'] : $payment['p2'];

        } else {

            $cases[$key]['total'] = ($payment['p1'] > $payment['p2']) ? $payment['p1'] : $payment['p2'];
        }
    }
}

在 Ruby 中,我将结果作为 MySQL 返回的数组(使用 mysql2 gem)。使用下面的循环,它打印每一行。不提供密钥时如何检查密钥是否存在?

在 Ruby 中实现此代码的最佳方式是什么?如何在 Ruby 中将哈希添加到哈希中,类似于将数组添加到 PHP 中的数组。

results.each(:as => :array) do |row|
    puts row.inspect
end

更多解释:

PHP 结构

Array(
    0 => Array(
        Array(
            [id] => 'random id',
            [p1] => 534,
            [p2] => 105
        ),
        Array(
            [id] => 'random id',
            [p1] => 335,
            [p2] => 425
        )
    ),
    1 => Array(
        Array(
            [id] => 'random id',
            [p1] => 259,
            [p2] => 124
        )
    )
)

我正在尝试遍历第一个数组中的每个数组,如果 p1 > p2,则将 p1 添加到该数组的总键中。即,0 索引看起来像这样:

0 => Array(
    'total' => 959,
    Array(
        [id] => 'random id',
        [p1] => 534,
        [p2] => 105
    ),
    Array(
        [id] => 'random id',
        [p1] => 335,
        [p2] => 425
    )
)

【问题讨论】:

    标签: php ruby arrays hash


    【解决方案1】:

    您要按result['id'] 分组吗?我相信将您的 PHP 代码“翻译”为 ruby​​ 将如下所示:

    cases = {}
    results.each do |result|
      if cases[result['id']]
        cases[result['id']] << result
      else
        cases[result['id']] = [result]
      end
    end
    

    获得相同结果的另一种方法是使用group_by

    cases = results.group_by { |result| result['id'] }
    

    “翻译”为 ruby​​ 的第二部分将如下所示:

    cases.each do |key, c|
      c.each do |payment|
        if c.count > 1 
          c['total'] += (payment['p1'] > payment['p2']) ? payment['p1'] : payment['p2']
        else
          c['total'] = (payment['p1'] > payment['p2']) ? payment['p1'] : payment['p2']
        end
      end
    end
    

    (这实际上在 ruby​​ 中不起作用,因为数组不能有像 'total' 这样的任意键 - 它只接受括号中的数字。您必须修改此代码以将总数保存在不同的结构中)

    同样,总结'p1''p2' 在每种情况下每次付款的最大值的更惯用方式可能看起来更像这样:

    totals = cases.values.map do |c|
      c.inject(0) { |sum, payment| sum + [payment['p1'], payment['p2']].max }
    end
    

    【讨论】:

    • 这只是第一部分。
    • @nmm59 - 添加了另一部分
    猜你喜欢
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 2021-10-16
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多