如何在数组中找到不同情况的第一个字符串?

时间:2017-06-20 19:28:06

标签: ruby

我有一个字符串数组,并且至少包含一个字母:

["abc", "FFF", "EEE"]

如何找到与数组中任何先前字符串不同的第一个字符串的索引?该函数应为1提供以上内容:

FFF".eql?("FFF".upcase)

并且该条件对于数组中的任何先前字符串都不是真的,而是:

["P", "P2F", "ccc", "DDD"]

应该产生2,因为"ccc"没有大写,而且它的所有前身都是。

我知道如何找到第一个使用

大写的字符串
string_tokens.find_index { |w| w == w.upcase }

但我无法弄清楚如何调整以上内容以解决不同的情况。

4 个答案:

答案 0 :(得分:2)

你可以拿走每对连续元素并比较它们的大写。如果它们不同,则返回索引。

def detect_case_change(ary)
  ary.each_cons(2).with_index(1) do |(a, b), idx|
    return idx if (a == a.upcase) != (b == b.upcase)
  end
  nil
end

detect_case_change ["abc", "FFF", "EEE"] # => 1
detect_case_change ["P", "P2F", "ccc", "DDD"] # => 2

答案 1 :(得分:1)

这使得对您的数据的一些假设完全由' A' ...' Z'和' ...' z':

def find_case_mismatch(list)
  index = list.each_cons(2).to_a.index do |(a,b)|
    a[0].ord & 32 != b[0].ord & 32
  end

  index && index + 1
end

比较字符值。 ' A'不同于' a'一位,该位始终在同一位置(0x20)。

答案 2 :(得分:1)

Enumerable#chunk为这项任务提供了很多帮助。

  

枚举项目,根据返回值将它们组合在一起   块的值。返回同一块的连续元素   价值被捏在一起。

l1 = ["abc", "FFF", "EEE"]
l2 = ["P", "P2F", "ccc", "DDD"]
p l1.chunk{|s| s == s.upcase }.to_a
# [[false, ["abc"]], [true, ["FFF", "EEE"]]]
p l2.chunk{|s| s == s.upcase }.to_a
# [[true, ["P", "P2F"]], [false, ["ccc"]], [true, ["DDD"]]]

您需要索引这一事实使其可读性稍差,但这是一个例子。所需的索引(如果存在)是第一个块的大小:

p l1.chunk{|s| s == s.upcase }.first.last.size
# 1
p l2.chunk{|s| s == s.upcase }.first.last.size
# 2

如果案件根本没有变化,它会返回整个数组的长度:

p %w(aaa bbb ccc ddd).chunk{|s| s == s.upcase }.first.last.size
# 4

答案 3 :(得分:0)

我假设数组的每个元素(字符串)至少包含一个字母和相同大小写的字母。

def first_case_change_index(arr)
  s = arr.map { |s| s[/[[:alpha:]]/] }.join
  (s[0] == s[0].upcase ? s.swapcase : s) =~ /[[:upper:]]/
end

first_case_change_index ["abc", "FFF", "EEE"] #=> 1
first_case_change_index ["P", "P2F", "ccc"]   #=> 2
first_case_change_index ["P", "P2F", "DDD"]   #=> nil

步骤如下。

arr = ["P", "2PF", "ccc"]

a = arr.map { |s| s[/[[:alpha:]]/] }
  #=> ["P", "P", "c"]
s = a.join
  #=> "PPc"
s[0] == s[0].upcase
  #=> "P" == "P"
  #=> true
t = s.swapcase
  #=> "ppC"
t =~ /[[:upper:]]/
  #=> 2

这是另一种方式。

def first_case_change_index(arr)
  look_for_upcase = (arr[0] == arr[0].downcase)
  arr.each_index.drop(1).find do |i|
    (arr[i] == arr[i].upcase) == look_for_upcase
  end
end