Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.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
Markdown 对嵌套降价列表排序?_Markdown_Sublimetext3_Sublimetext - Fatal编程技术网

Markdown 对嵌套降价列表排序?

Markdown 对嵌套降价列表排序?,markdown,sublimetext3,sublimetext,Markdown,Sublimetext3,Sublimetext,我正在寻找一个脚本,方法或工具排序嵌套降价清单。我使用升华文本,它有一个内置的排序行函数,但是这个函数破坏了任何嵌套列表的顺序。例如,如果我要排序: * Zoo Animals * Herbivores * Zebra * Gazelle * Carnivores * Tiger * Lion * Omnivores * Gorilla * Baboon * C

我正在寻找一个脚本,方法或工具排序嵌套降价清单。我使用升华文本,它有一个内置的排序行函数,但是这个函数破坏了任何嵌套列表的顺序。例如,如果我要排序:

* Zoo Animals
    * Herbivores
        * Zebra
        * Gazelle
    * Carnivores
        * Tiger
        * Lion
    * Omnivores
        * Gorilla
        * Baboon
        * Chimpanzee
* Domestic Animals
    * Canines
        * German Shepherd
        * Cocker Spaniel
使用升华排序行函数,我得到:

        * Baboon
        * Chimpanzee
        * Cocker Spaniel
        * Gazelle
        * German Shepherd
        * Gorilla
        * Lion
        * Tiger
        * Zebra
    * Canines
    * Carnivores
    * Herbivores
    * Omnivores
* Domestic Animals
* Zoo Animals
显然,这不是我想要的。我想要的是一个“范围排序”,它相对于每个项目符号级别进行排序,而不破坏嵌套关系,如下所示:

* Domestic Animals
    * Canines
        * Cocker Spaniel
        * German Shepherd
* Zoo Animals
    * Carnivores
        * Lion
        * Tiger
    * Herbivores
        * Gazelle
        * Zebra
    * Omnivores
        * Baboon
        * Chimpanzee
        * Gorilla
以下是我研究过的一些事情以及我对每一件事情的想法:

  • 使用升华包进行排序。我找不到。然而,也许有一种方法可以使用CSSComb包并使其适应降价列表
  • 使用sublime中的手动过程对列表进行排序,可能通过选择项目符号级别并按这些级别排序?问题是,要排序的行的选择必须在同一缩进级别,并且不能被另一缩进级别的任何其他行分隔,否则排序将完全混乱。除非我遗漏了什么
  • 使用脚本对行进行排序。我对ruby很熟悉,所以也许有一种方法可以将这个列表导入ruby,并将嵌套的列表当作一个嵌套的散列来处理。我确信使用ruby脚本可以实现我的目标,但如果已经有解决方案可用,我不想走这条路
如何对大型嵌套降价列表进行排序

更新#1:

@J4G创建了一个伟大的Atom包,解决了最初的排序问题,链接见他的答案

前面的列表是一个没有代码块和编号列表的简单列表。然而,在对现实生活中的降价列表进行排序时,我们有代码块、编号列表和以特殊字符开头的行,嵌套在列表中,如下所示:

* Commands
    * Migrations
        * `rake db:migrate` - push all migrations to the database
        * 'STEP=3' - revert the last 3 migrations
    * `Rails`
        * `c` - start rails console, run code from your app!
    * `Rake`
        * Rake Task
        ```ruby
        desc 'process csv'
        task process_csv: :environment do
            Node.process_csv
        end
        ```
* Package Upgrade Status:
    1. Install Package
    2. Attach Plugin
    3. Review Installation
    ~~~
    |Install|Status|
    |Yes|Pending|
    ~~~

排序后,我认为上面的标记列表应该返回不变,因为记号和引号没有排序意义,代码块/编号列表已经按照正确的顺序创建。

这是使用Ruby实现的一种方法。假设字符串由变量
str
持有

代码

def sort_indented(str)
  arr = str.lines.map { |s| [indentation(s), s.chomp] }
  indent_offset = arr.map(&:first).uniq.sort.each_with_index.
    with_object({}) { |(indent, i),h| h[indent] = i }
  dim_size = indent_offset.size 
  prev = []
  arr.map do |indent, s|
    a = ['']*dim_size
    offset = indent_offset[indent]
    a[offset] = s
    a[0,offset] = prev.first(offset)
    prev = a
    a
  end.sort.map { |a| a[a.rindex { |s| s != '' }] }.join("\n") 
end

def indentation(s)
  s[/^\s*/].size
end
str =<<THE_END 
* Zoo Animals
    * Herbivores
        * Zebra
        * Gazelle
    * Carnivores
        * Tiger
        * Lion
    * Omnivores
        * Gorilla
        * Baboon
        * Chimpanzee
* Domestic Animals
    * Canines
        * German Shepherd
        * Cocker Spaniel
THE_END
示例

def sort_indented(str)
  arr = str.lines.map { |s| [indentation(s), s.chomp] }
  indent_offset = arr.map(&:first).uniq.sort.each_with_index.
    with_object({}) { |(indent, i),h| h[indent] = i }
  dim_size = indent_offset.size 
  prev = []
  arr.map do |indent, s|
    a = ['']*dim_size
    offset = indent_offset[indent]
    a[offset] = s
    a[0,offset] = prev.first(offset)
    prev = a
    a
  end.sort.map { |a| a[a.rindex { |s| s != '' }] }.join("\n") 
end

def indentation(s)
  s[/^\s*/].size
end
str =<<THE_END 
* Zoo Animals
    * Herbivores
        * Zebra
        * Gazelle
    * Carnivores
        * Tiger
        * Lion
    * Omnivores
        * Gorilla
        * Baboon
        * Chimpanzee
* Domestic Animals
    * Canines
        * German Shepherd
        * Cocker Spaniel
THE_END
一般方法

Ruby对数组进行排序时,例如:

a = [1,2,4]
b = [4,5,6]
c = [1,2,3,5]]
[a, b, c]
它将首先按每个数组的第一个元素进行排序。由于
a
c
在偏移量0处具有相同的元素
1
,并且
b
在该偏移量处具有
4
,因此
a
c
在排序数组中都将位于
b
之前。Ruby通过查看
a
c
的第二个元素来打破僵局。由于它们都等于
2
,Ruby接着进入第三个元素,在这里,关系破裂:
c
a
之前,因为
3<4

我将
arr
转换为以下数组:

result =     
[["* Zoo Animals"     , ""                , ""],
 ["* Zoo Animals"     , "    * Herbivores", ""],
 ["* Zoo Animals"     , "    * Herbivores", "        * Zebra"],
 ["* Zoo Animals"     , "    * Herbivores", "        * Gazelle"],
 ["* Zoo Animals"     , "    * Carnivores", ""],
 ["* Zoo Animals"     , "    * Carnivores", "        * Tiger"],
 ["* Zoo Animals"     , "    * Carnivores", "        * Lion"], 
 ["* Zoo Animals"     , "    * Omnivores" , ""],
 ["* Zoo Animals"     , "    * Omnivores" , "        * Gorilla"],
 ["* Zoo Animals"     , "    * Omnivores" , "        * Baboon"],
 ["* Zoo Animals"     , "    * Omnivores" , "        * Chimpanzee"],
 ["* Domestic Animals", ""                , ""],
 ["* Domestic Animals", "    * Canines"   , ""],
 ["* Domestic Animals", "    * Canines"   , "        * German Shepherd"],
 ["* Domestic Animals", "    * Canines"   , "        * Cocker Spaniel"]]
使用此表单后,我们可以排序:

result.sort
  #=> [["* Domestic Animals", "", ""],
  #    ["* Domestic Animals", "    * Canines", ""],
  #    ["* Domestic Animals", "    * Canines", "        * Cocker Spaniel"],
  #    ["* Domestic Animals", "    * Canines", "        * German Shepherd"],
  #    ["* Zoo Animals", "", ""], ["* Zoo Animals", "    * Carnivores", ""],
  #    ["* Zoo Animals", "    * Carnivores", "        * Lion"],
  #    ["* Zoo Animals", "    * Carnivores", "        * Tiger"],
  #    ["* Zoo Animals", "    * Herbivores", ""],
  #    ["* Zoo Animals", "    * Herbivores", "        * Gazelle"],
  #    ["* Zoo Animals", "    * Herbivores", "        * Zebra"],
  #    ["* Zoo Animals", "    * Omnivores", ""],
  #    ["* Zoo Animals", "    * Omnivores", "        * Baboon"],
  #    ["* Zoo Animals", "    * Omnivores", "        * Chimpanzee"],
  #    ["* Zoo Animals", "    * Omnivores", "        * Gorilla"]] 
最后一步是从排序数组的每个元素中提取最后一个非空字符串

详细说明

首先,我们定义一个助手方法来计算字符串的缩进:

def indentation(s)
  s[/^\s*/].size
end
比如说,

            #1234
indentation("    * Herbivores")
  #=> 4
现在,让我们将字符串转换为行数组:

a = str.lines
  #=> ["* Zoo Animals\n",
  #    "    * Herbivores\n",
  #    "        * Zebra\n",
  #    "        * Gazelle\n",
  #    "    * Carnivores\n",
  #    "        * Tiger\n",
  #    "        * Lion\n",
  #    "    * Omnivores\n",
  #    "        * Gorilla\n",
  #    "        * Baboon\n",
  #    "        * Chimpanzee\n",
  #    "* Domestic Animals\n",
  #    "    * Canines\n",
  #    "        * German Shepherd\n",
  #    "        * Cocker Spaniel\n"]
接下来,我们将
a
转换为成对数组,成对数组中的第二个元素是
a
的元素(一个字符串),换行符从末尾截断,第一个是缩进:

arr = a.map { |s| [indentation(s), s.chomp] }
  # => [[0, "* Zoo Animals"],        [4, "    * Herbivores"],
  #     [8, "        * Zebra"],      [8, "        * Gazelle"],
  #     [4, "    * Carnivores"],     [8, "        * Tiger"],
  #     [8, "        * Lion"],       [4, "    * Omnivores"],
  #     [8, "        * Gorilla"],    [8, "        * Baboon"],
  #     [8, "        * Chimpanzee"], [0, "* Domestic Animals"],
  #     [4, "    * Canines"],        [8, "        * German Shepherd"],
  #     [8, "        * Cocker Spaniel"]] 
事实上,我们将在一个步骤中执行前两个操作:

arr = str.lines.map { |s| [indentation(s), s.chomp] }
接下来,我们需要知道使用的缩进:

indents = arr.map { |pair| pair.first }
  #=> [0, 4, 8, 8, 4, 8, 8, 4, 8, 8, 8, 0, 4, 8, 8] 
我们可以更经济地这样写:

indents = arr.map(&:first)
要查找我们编写的唯一缩进,请执行以下操作:

unique = indents.uniq
  #=> [0, 4, 8] 
如果它们不整齐,我们应该对它们进行分类:

sorted = unique.sort
  #=> [0, 4, 8] 
三个缩进中的每一个都将对应于我们将要排序的数组中的偏移量,因此构建哈希非常方便:

indent_offset = sorted.each_with_index.with_object({}) do |(indent, i),h|
  h[indent] = i
end
  #=> {0=>0, 4=>1, 8=>2}
同样,我们可以通过组合几个步骤来执行此计算:

indent_offset = arr.map(&:first).uniq.sort.each_with_index.
  with_object({}) { |(indent, i),h| h[indent] = i }
接下来,我们用字符串的三元素数组替换
arr
的每个元素:

dim_size = indent_offset.size 
  #=> 3
prev = []
result = arr.map do |indent, s|
  a = ['']*dim_size
  offset = indent_offset[indent]
  a[offset] = s
  a[0,offset] = prev.first(offset)
  prev = a
  a
end
这个计算的结果是我在上面的一般方法下给出的第一个数组。我们现在可以对
结果进行排序
,以获得我在常规方法下给出的第二个数组:

最后两个步骤是用最后一个非空字符串替换排序后的
的每个元素(三元素数组):

sorted_strings = sorted.map { |a| a[a.rindex { |s| s != '' }] }
然后将这些字符串合并为一个字符串:

sorted_strings.join("\n")

如果你有兴趣使用(我强烈推荐它作为升华的免费替代品),我只是做了一个软件包来满足你的需要


看起来没有人能解决这个问题。如果你愿意的话,我可以很快在Node中编写一个。这似乎比使用Ruby或其他通用脚本语言更好地执行所需排序。哇,回答得非常透彻!也许有一天它会变成红宝石。谢谢,但我想已经有红宝石做得更好了。当我写这篇文章的时候,我在想应该有一个更好的方法来使用Ruby。