在链式调用中访问结果数组大小
Accessing result array size in chained call
我正在尝试编写一个单行代码来从 VirtualBox 的仅主机接口列表的输出中创建一个散列。看起来像这样
Name: vboxnet0
GUID: 77777777-6666-4444-8888-020227202302
DHCP: Disabled
IPAddress: 192.168.42.1
NetworkMask: 255.255.255.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: 0a:00:27:00:00:00
MediumType: Ethernet
Status: Up
VBoxNetworkName: HostInterfaceNetworking-vboxnet0
Name: vboxnet1
GUID: 77777777-6666-4444-8888-020227202301
DHCP: Disabled
IPAddress: 172.16.0.1
NetworkMask: 255.255.255.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: 0a:00:27:00:00:01
MediumType: Ethernet
Status: Up
VBoxNetworkName: HostInterfaceNetworking-vboxnet1
我试过了:
Hash[*`VBoxManage list hostonlyifs`.split("\n").reject(&:empty?).collect {|s| s.split(/:\ */)}.flatten(1)]
结果是:
=> {"Name"=>"vboxnet1", "GUID"=>"786f6276-656e-4174-8000-0a0027000001", "DHCP"=>"Disabled", "IPAddress"=>"172.16.0.1", "NetworkMask"=>"255.255.255.0", "IPV6Address"=>"IPV6NetworkMaskPrefixLength", "0"=> "HardwareAddress", "0a"=>"00", "27"=>"00", "00"=>"01", "MediumType"=>"Ethernet", "Status"=>"Up", "VBoxNetworkName"=>"HostInterfaceNetworking-vboxnet1"}
几乎是我想要的,但仅限于第一个界面。我在想:"Okay, slice the array into half and convert each half to a hash!".
我的问题是如何获取flatten方法返回的Array的大小,并在slice方法的参数中使用它,而不是将其分配给变量等?
我的意思是:
`VBoxManage list hostonlyifs`.split("\n").reject(&:empty?).collect {|s| s.split(/:\ */)}.flatten(1).slice(0..>>>how_to_access_result_object_of_flatten_here<<<.size/2)
我在 Ruby 方面经验不足,如果问题很明显,我很抱歉,但我尝试了很多谷歌搜索都无济于事。
编辑:split
在 ?closure/lambda?传递给 collect
是不正确的,因为它 returns 只有一个字符串(对于散列转换来说应该是两个字符串)如果在冒号之后只有 spaces 就是这种情况以 IPV6Address:
开头的行(示例中不可见)。我将其更改为 split(/:\ /)
,现在可以使用了。 space 是必需的,因为仅使用冒号也会拆分 MAC 地址。
除非有一些我从未见过的特殊 Ruby 巫术,否则我很确定简单的答案是你不能。
但是,下一个最佳方法(而不是将数组分配给变量)是扩展 Array
class 并编写一个额外的方法,如下所示:
class Array
def flatten_and_slice
flattened_result = self.flatten(1)
self.slice(0..flattened_result.size/2)
end
end
然后你就调用你的新方法。
`VBoxManage list hostonlyifs`.split("\n").reject(&:empty?).collect {|s| s.split(/:\ */)}.flatten_and_slice
您可以将输出拆分为 ^$
并获取您想要的接口:
text = `VBoxManage list hostonlyifs`
Hash[*text.split(/^$/)[0].split(/\n/).flat_map {|line| line.split(":", 2).map(&:strip) }]
text.split(/^$/)[0]
将文本拆分为空行,取第一个界面。然后,我们只需将该文本拆分成单独的行,拆分成 [key, value] 对,并将其映射到哈希中,即可将其解析为哈希。这给出如下输出:
{
"Name" => "vboxnet0",
"GUID" => "77777777-6666-4444-8888-020227202302",
"DHCP" => "Disabled",
"IPAddress" => "192.168.42.1",
"NetworkMask" => "255.255.255.0",
"IPV6Address" => "",
"IPV6NetworkMaskPrefixLength" => "0",
"HardwareAddress" => "0a:00:27:00:00:00",
"MediumType" => "Ethernet",
"Status" => "Up",
"VBoxNetworkName" => "HostInterfaceNetworking-vboxnet0"
}
如果要生成一个散列数组,每个接口一个,拆分文本,然后将每个文本块映射到一个散列中:
text.split(/^$/).map {|chunk| Hash[*chunk.split(/\n/).flat_map {|line| line.split(":", 2).map(&:strip) }] }
导致:
[
[0] {
"Name" => "vboxnet0",
"GUID" => "77777777-6666-4444-8888-020227202302",
"DHCP" => "Disabled",
"IPAddress" => "192.168.42.1",
"NetworkMask" => "255.255.255.0",
"IPV6Address" => "",
"IPV6NetworkMaskPrefixLength" => "0",
"HardwareAddress" => "0a:00:27:00:00:00",
"MediumType" => "Ethernet",
"Status" => "Up",
"VBoxNetworkName" => "HostInterfaceNetworking-vboxnet0"
},
[1] {
"Name" => "vboxnet1",
"GUID" => "77777777-6666-4444-8888-020227202301",
"DHCP" => "Disabled",
"IPAddress" => "172.16.0.1",
"NetworkMask" => "255.255.255.0",
"IPV6Address" => "",
"IPV6NetworkMaskPrefixLength" => "0",
"HardwareAddress" => "0a:00:27:00:00:01",
"MediumType" => "Ethernet",
"Status" => "Up",
"VBoxNetworkName" => "HostInterfaceNetworking-vboxnet1"
}
]
我正在尝试编写一个单行代码来从 VirtualBox 的仅主机接口列表的输出中创建一个散列。看起来像这样
Name: vboxnet0
GUID: 77777777-6666-4444-8888-020227202302
DHCP: Disabled
IPAddress: 192.168.42.1
NetworkMask: 255.255.255.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: 0a:00:27:00:00:00
MediumType: Ethernet
Status: Up
VBoxNetworkName: HostInterfaceNetworking-vboxnet0
Name: vboxnet1
GUID: 77777777-6666-4444-8888-020227202301
DHCP: Disabled
IPAddress: 172.16.0.1
NetworkMask: 255.255.255.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: 0a:00:27:00:00:01
MediumType: Ethernet
Status: Up
VBoxNetworkName: HostInterfaceNetworking-vboxnet1
我试过了:
Hash[*`VBoxManage list hostonlyifs`.split("\n").reject(&:empty?).collect {|s| s.split(/:\ */)}.flatten(1)]
结果是:
=> {"Name"=>"vboxnet1", "GUID"=>"786f6276-656e-4174-8000-0a0027000001", "DHCP"=>"Disabled", "IPAddress"=>"172.16.0.1", "NetworkMask"=>"255.255.255.0", "IPV6Address"=>"IPV6NetworkMaskPrefixLength", "0"=> "HardwareAddress", "0a"=>"00", "27"=>"00", "00"=>"01", "MediumType"=>"Ethernet", "Status"=>"Up", "VBoxNetworkName"=>"HostInterfaceNetworking-vboxnet1"}
几乎是我想要的,但仅限于第一个界面。我在想:"Okay, slice the array into half and convert each half to a hash!".
我的问题是如何获取flatten方法返回的Array的大小,并在slice方法的参数中使用它,而不是将其分配给变量等?
我的意思是:
`VBoxManage list hostonlyifs`.split("\n").reject(&:empty?).collect {|s| s.split(/:\ */)}.flatten(1).slice(0..>>>how_to_access_result_object_of_flatten_here<<<.size/2)
我在 Ruby 方面经验不足,如果问题很明显,我很抱歉,但我尝试了很多谷歌搜索都无济于事。
编辑:split
在 ?closure/lambda?传递给 collect
是不正确的,因为它 returns 只有一个字符串(对于散列转换来说应该是两个字符串)如果在冒号之后只有 spaces 就是这种情况以 IPV6Address:
开头的行(示例中不可见)。我将其更改为 split(/:\ /)
,现在可以使用了。 space 是必需的,因为仅使用冒号也会拆分 MAC 地址。
除非有一些我从未见过的特殊 Ruby 巫术,否则我很确定简单的答案是你不能。
但是,下一个最佳方法(而不是将数组分配给变量)是扩展 Array
class 并编写一个额外的方法,如下所示:
class Array
def flatten_and_slice
flattened_result = self.flatten(1)
self.slice(0..flattened_result.size/2)
end
end
然后你就调用你的新方法。
`VBoxManage list hostonlyifs`.split("\n").reject(&:empty?).collect {|s| s.split(/:\ */)}.flatten_and_slice
您可以将输出拆分为 ^$
并获取您想要的接口:
text = `VBoxManage list hostonlyifs`
Hash[*text.split(/^$/)[0].split(/\n/).flat_map {|line| line.split(":", 2).map(&:strip) }]
text.split(/^$/)[0]
将文本拆分为空行,取第一个界面。然后,我们只需将该文本拆分成单独的行,拆分成 [key, value] 对,并将其映射到哈希中,即可将其解析为哈希。这给出如下输出:
{
"Name" => "vboxnet0",
"GUID" => "77777777-6666-4444-8888-020227202302",
"DHCP" => "Disabled",
"IPAddress" => "192.168.42.1",
"NetworkMask" => "255.255.255.0",
"IPV6Address" => "",
"IPV6NetworkMaskPrefixLength" => "0",
"HardwareAddress" => "0a:00:27:00:00:00",
"MediumType" => "Ethernet",
"Status" => "Up",
"VBoxNetworkName" => "HostInterfaceNetworking-vboxnet0"
}
如果要生成一个散列数组,每个接口一个,拆分文本,然后将每个文本块映射到一个散列中:
text.split(/^$/).map {|chunk| Hash[*chunk.split(/\n/).flat_map {|line| line.split(":", 2).map(&:strip) }] }
导致:
[
[0] {
"Name" => "vboxnet0",
"GUID" => "77777777-6666-4444-8888-020227202302",
"DHCP" => "Disabled",
"IPAddress" => "192.168.42.1",
"NetworkMask" => "255.255.255.0",
"IPV6Address" => "",
"IPV6NetworkMaskPrefixLength" => "0",
"HardwareAddress" => "0a:00:27:00:00:00",
"MediumType" => "Ethernet",
"Status" => "Up",
"VBoxNetworkName" => "HostInterfaceNetworking-vboxnet0"
},
[1] {
"Name" => "vboxnet1",
"GUID" => "77777777-6666-4444-8888-020227202301",
"DHCP" => "Disabled",
"IPAddress" => "172.16.0.1",
"NetworkMask" => "255.255.255.0",
"IPV6Address" => "",
"IPV6NetworkMaskPrefixLength" => "0",
"HardwareAddress" => "0a:00:27:00:00:01",
"MediumType" => "Ethernet",
"Status" => "Up",
"VBoxNetworkName" => "HostInterfaceNetworking-vboxnet1"
}
]