【问题标题】:How to Sort Everything in an Array Except Special Chars - Ruby如何对数组中除特殊字符外的所有内容进行排序 - Ruby
【发布时间】:2021-07-19 12:10:04
【问题描述】:

我正在尝试按字母顺序对一组字母进行排序,但将特殊字符保留在 ruby​​ 中的同一位置。

例如,

word = ["f", "a", "s", "t", "-", "c", "a", "r", "s"]

如何按字母顺序对整个内容进行排序,但将“-”保留在原处。如果我对现在的情况进行排序,那么“-”将出现在我不想要的前面。我尝试了十五种不同的方法,但我无法弄清楚。你能帮忙吗?

【问题讨论】:

  • 你希望转换后的数组是什么样子的?
  • @ToddA.Jacobs "a", "a", "c", "f", "-", "r", "s", "s", "t"]
  • 哦!刚刚意识到一件事!也许我可以通过它的原始索引添加它?遍历第一个数组,找到特殊char的索引,遍历第二个数组,在索引处使用insert方法?
  • @anothernewbiecoder 是的,这行得通。如果你弄明白了,然后发布你的答案(你可以回答你自己的问题)。
  • @ToddA.Jacobs 让它工作,我想我所要做的就是把它贴在这里哈哈

标签: arrays ruby sorting question-answering


【解决方案1】:

一些非常冗长的方法来解释你需要实现的逻辑。有一些“更清洁”的方法可以实现这一点,但我觉得这可以提供更多的理解。

为数组添加额外的特殊字符以获得更好的测试覆盖率:

let(:input) { ["f", "a", "s", "t", "-", "c", "a", "r", "s", "/"] }
let(:desired_output) { ["a", "a", "c", "f", "-", "r", "s", "s", "t", "/"] }

it "takes the input and gives the desired output" do
  expect(sort_alphanumeric_characters(input)).to eq(desired_output)
end

在数组上调用.map.select 以枚举值,然后调用.with_index,因为您需要保留索引以供以后使用。

def sort_alphanumeric_characters(word_as_array)
  # assuming you mean non-alphanumeric
  # collect those indicies which are 'special' characters
  # the regex matches the string with anything outside of the alphanumeric range. Note the '^'
  special_character_indicies = word_as_array.map.with_index { |val, indx| indx if val =~ /[^a-zA-Z0-9]/ }.compact
  # collect all characters by index that were not yielded as 'special'
  alphanumeric_array = word_as_array.select.with_index { |char, indx| char unless special_character_indicies.include? indx }
  # sort the alphanumeric array
  sorted_alphanumeric_array = alphanumeric_array.sort
  # use Array#insert to place the 'special' by index
  special_character_indicies.each do |special_indx|
    special_char = word_as_array[special_indx]
    sorted_alphanumeric_array.insert(special_indx, special_char)
  end
  # return desired output
  sorted_alphanumeric_array
end

【讨论】:

  • 有什么方法可以做到这一点?想了很多,感觉自己就在身边,却看不到。我在想 insert 真的很有帮助!
  • 上面都列出了,不是吗?
  • 哦,我还以为你在说除此之外还有其他东西!
【解决方案2】:

我一发帖就得到了一道闪电(当它发生时我很喜欢)。这确实不是一个很好的解决方案,但它确实有效!

    def scramble_words(str)
      idx = 0 
      chars = str.delete("^a-z").chars
      first_ele = chars.shift
      last_ele = chars.pop
    
      str.chars.each_with_index {|c, i| idx = i if c =~ /[^a-z" "]/ }
    
      (first_ele + chars.sort.join  + last_ele).insert(idx, str[idx])
    
    end
    
    p scramble_words('card-carrying') == 'caac-dinrrryg'
    p scramble_words("shan't") == "sahn't"
    p scramble_words('-dcba') == '-dbca'

【讨论】:

  • scramble_words 'this-HAS-more-THAN-one-SPECIAL-character-AND-capslocks-WORDS' IndexError: index 59 out of string 所以你正在使用正则表达式删除很多字符,并且只希望该解决方案中有一个特殊字符
  • 第一个和最后一个字符的处理方式不同。如果这是您期望的实际输出,您应该相应地更新您的问题。 (也包括你的问题中的这些例子)
  • 哦,是的!我没有告诉那部分。第一个和最后一个字母和特殊字符保持在同一个位置。然后中间就乱了。
  • 我没有添加那部分的原因是因为我知道那部分。我一直在努力的部分是将特殊字符保留在那里并对其他所有内容进行排序。我展示了整个问题,但我可以改变它吗?
  • @benjessop 没错!起初我没有想到这一点,然后我遇到了一个测试用例,它有多个特殊字符并且有一个重要的 facepalm 时刻。我结束了将其切换为哈希。因此,我遍历了将所有特殊字符放入哈希的字符串。然后在最后我插入了它们。
猜你喜欢
  • 2014-01-22
  • 1970-01-01
  • 2015-07-03
  • 2012-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-23
  • 2021-10-28
相关资源
最近更新 更多