Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Ruby中对多个目录项进行排序_Ruby - Fatal编程技术网

在Ruby中对多个目录项进行排序

在Ruby中对多个目录项进行排序,ruby,Ruby,如果我有以下文件,并且它们有以下路径(为简单起见进行了更改) 我如何对它们进行排序以得到这样的散列 sort_directory(array) #=> { "dir1" => { "a" => [ "root_path/dir1/a/file.jpg", "root_path/dir1/a/file2.jpg" ], "b" => [ "root_path/dir1/b/file3.jpg" ]

如果我有以下文件,并且它们有以下路径(为简单起见进行了更改)

我如何对它们进行排序以得到这样的散列

sort_directory(array)

#=> 
{ 
  "dir1" => {
    "a" => [
      "root_path/dir1/a/file.jpg",
      "root_path/dir1/a/file2.jpg"
    ],
    "b" => [
      "root_path/dir1/b/file3.jpg"
    ]
  },
  "dir2" => {
    "c" => [
      "root_path/dir2/c/file4.jpg"
    ]
  }
}   
使用、和/或某些正则表达式的一种方法

array.group_by{ |dir| dir.split('/')[1] }.map{ |k,v| {k => v.group_by{ |file| file[/\/([^\/]+)(?=\/[^\/]+\/?\Z)/, 1]} } }

下面是如何使用递归来获得所需的结果

如果
s=“root\u path/dir1/a/b/c/file.jpg”
,我们可以认为
“root\u path”
位于“位置”0,
“dir1”
位于位置1,依此类推。OP给出的示例需要对位置1和2处的值进行分组,我将编写
positions=[1,2]

分组的位置数量或顺序没有限制。对于上面的字符串,我们可以编写,例如,
positions=[2,4,1]
,因此第一个分组将位于位置2,第二个分组位于位置4,最后一个分组位于位置1(尽管我不知道这是否有意义)

代码

def hashify(arr, positions)
  recurse(positions, arr.map { |s| s.split("/") })
end

def recurse(positions, parts)
  return parts.map { |a| a.join('/') } if positions.empty?
  pos, *positions = positions
  h = parts.group_by { |a| a[pos] }.
            each_with_object({}) { |(k,a),g| g[k]=recurse(positions, a) }
end
arr = ["root_path/dir1/a/file.jpg",
       "root_path/dir1/a/file2.jpg",
       "root_path/dir1/b/file3.jpg",
       "root_path/dir2/c/file4.jpg"]

hashify(arr, [1, 2])
  #=>{"dir1"=>{"a"=>["root_path/dir1/a/file.jpg", "root_path/dir1/a/file2.jpg"],
  #            "b"=>["root_path/dir1/b/file3.jpg"]},
  #   "dir2"=>{"c"=>["root_path/dir2/c/file4.jpg"]}}
示例

def hashify(arr, positions)
  recurse(positions, arr.map { |s| s.split("/") })
end

def recurse(positions, parts)
  return parts.map { |a| a.join('/') } if positions.empty?
  pos, *positions = positions
  h = parts.group_by { |a| a[pos] }.
            each_with_object({}) { |(k,a),g| g[k]=recurse(positions, a) }
end
arr = ["root_path/dir1/a/file.jpg",
       "root_path/dir1/a/file2.jpg",
       "root_path/dir1/b/file3.jpg",
       "root_path/dir2/c/file4.jpg"]

hashify(arr, [1, 2])
  #=>{"dir1"=>{"a"=>["root_path/dir1/a/file.jpg", "root_path/dir1/a/file2.jpg"],
  #            "b"=>["root_path/dir1/b/file3.jpg"]},
  #   "dir2"=>{"c"=>["root_path/dir2/c/file4.jpg"]}}
解释

递归方法很难解释。在我看来,最好的方法是插入
put
语句来显示计算顺序。每当该方法调用自身时,我也缩进了一些空格。下面是如何为此目的修改代码

INDENT = 4

def hashify(arr, positions)
  recurse(positions, arr.map { |s| s.split("/") }, 0)
end

def recurse(positions, parts, lvl)
    puts
    "lvl=#{lvl}".pr(lvl)
    "positions=#{ positions }".pr(lvl)
  if positions.empty?
    "parts=#{parts}".pr(lvl)
    return parts.map { |a| a.join('/') }
  end 
  pos, *positions = positions
    "pos=#{pos}, positions=#{positions}".pr(lvl)
  h = parts.group_by { |a| a[pos] }
    "h=#{h}".pr(lvl) 
  g = h.each_with_object({}) { |(k,a),g| g[k]=recurse(positions, a, lvl+1) }
    "rv=#{g}".pr(lvl)
  g
end

class String
  def pr(lvl)
    print "#{ ' ' * INDENT * lvl}"
    puts self
  end
end
现在,我们对示例中给出的数据执行此方法

hashify(arr, [1, 2])
lvl=0
positions=[1, 2]
pos=1, positions=[2]
h={"dir1"=>[["root_path", "dir1", "a", "file.jpg"],
            ["root_path", "dir1", "a", "file2.jpg"],
            ["root_path", "dir1", "b", "file3.jpg"]],
   "dir2"=>[["root_path", "dir2", "c", "file4.jpg"]]}

    lvl=1
    positions=[2]
    pos=2, positions=[]
    h={"a"=>[["root_path", "dir1", "a", "file.jpg"],
             ["root_path", "dir1", "a", "file2.jpg"]],
       "b"=>[["root_path", "dir1", "b", "file3.jpg"]]}

        lvl=2
        positions=[]
        parts=[["root_path", "dir1", "a", "file.jpg"],
               ["root_path", "dir1", "a", "file2.jpg"]]

        lvl=2
        positions=[]
        parts=[["root_path", "dir1", "b", "file3.jpg"]]


这一切都从
def sort\u目录(数组)
开始,然后继续。你试过什么?很好!如果你能一步一步地描述它是如何工作的,那就太好了。