如何检查ruby哈希中的匹配键?

时间:2017-09-22 07:14:29

标签: ruby hash

我正在学习编码,其中一项任务是返回键,返回喜欢同一电视节目的人的名字。

我已经设法让它工作并通过TDD,但我想知道我是否采取了“长途跋涉”并且可能有一个更简单的解决方案?

以下是设置和测试:

class TestFriends < MiniTest::Test

  def setup

    @person1 = {
      name: "Rick",
      age: 12,
      monies: 1,
      friends: ["Jay","Keith","Dave", "Val"],
      favourites: {
        tv_show: "Friends",
        things_to_eat: ["charcuterie"]
      }
    }

    @person2 = {
      name: "Jay",
      age: 15,
      monies: 2,
      friends: ["Keith"],
      favourites: {
        tv_show: "Friends",
        things_to_eat: ["soup","bread"]
      }
    }

    @person3 = {
      name: "Val",
      age: 18,
      monies: 20,
      friends: ["Rick", "Jay"],
      favourites: {
        tv_show: "Pokemon",
        things_to_eat: ["ratatouille", "stew"]
      }
    }

    @people = [@person1, @person2, @person3]

      end

      def test_shared_tv_shows
        expected = ["Rick", "Jay"]

        actual = tv_show(@people)

        assert_equal(expected, actual)
      end
    end

以下是我找到的解决方案:

def tv_show(people_list)
  tv_friends = {}
  for person in people_list
    if tv_friends.key?(person[:favourites][:tv_show]) == false
      tv_friends[person[:favourites][:tv_show]] = [person[:name]]
    else
      tv_friends[person[:favourites][:tv_show]] << person[:name]
    end
  end
  for array in tv_friends.values()
     if array.length() > 1
      return array
    end
  end
end

它通过了,但有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

我认为您可以使用Array#each替换这些for循环。但在您的情况下,当您使用people_list中的值创建哈希时,您可以使用Enumerable#each_with_object将新哈希指定为其对象参数,这样您就拥有了自己的{ {1}}来自person的哈希值以及新的&#34;空的&#34;哈希开始根据需要填写。

要检查内部哈希是否具有值为people_list的键,您可以检查其值是否为布尔值,可以跳过与false的比较,该值将被评估为false或true你的if语句。

您可以创建变量person[:favourites][:tv_show]tv_show以减少代码,然后通过name哈希在其值中选择长度大于1.因为这会在数组中为您提供一个数组,您可以使用tv_friends(或first)来获取第一个元素。

[0]

当方法调用没有参数时,你也可以省略括号。