从嵌套元组

时间:2017-01-18 23:14:03

标签: erlang tuples elixir

这是来自某个Erlang库的嵌套元组:

tuple = {:Certificate,
          {:TBSCertificate,
           :v3,
           3464270192823392628,
           {:AlgorithmIdentifier, {1, 2, 840, 113549, 1, 1, 11}, <<5, 0>>},
           {:Validity, {:utcTime, '160428162930Z'}, {:utcTime, '170528162930Z'}},
           :asn1_NOVALUE,
           :asn1_NOVALUE,
           :asn1_NOVALUE,
           :asn1_NOVALUE,
           :asn1_NOVALUE}}

为了找到:Validity元组,我需要做

tuple |> elem(1) |> elem(4)

我可以进行模式匹配,但是:asn1_NOVALUE中有太多get_in(tuple, [:Certificate, :Validity]) 我只是想忽略它们。

在Erlang / Elixir中还有其他方法可以获得嵌套的元组值吗?像

这样的东西
_.find(myCollection, ['myObj.some.Deep.Object.id', THE_VALUE_I_WANT])

3 个答案:

答案 0 :(得分:1)

我找到了here记录'TBSCertificate'的定义:

'TBSCertificate'{
      version,              % v1 | v2 | v3 
      serialNumber,         % integer() 
      signature,            % #'AlgorithmIdentifier'{} 
      issuer,               % {rdnSequence, [#AttributeTypeAndValue'{}]} 
      validity,             % #'Validity'{}
      subject,              % {rdnSequence, [#AttributeTypeAndValue'{}]} 
      subjectPublicKeyInfo, % #'SubjectPublicKeyInfo'{}
      issuerUniqueID,       % binary() | asn1_novalue
      subjectUniqueID,      % binary() | asn1_novalue
      extensions            % [#'Extension'{}] 
     }.

这是erlang符号,但我想它与elixir相当。在erlang中,您可以使用记录语法检索信息'Validity'

{_,TBScert} = Tuple,
Validity = Tuple#'TBSCertificate'.'Validity' % which is also a record

我不熟悉elixir的语法,我认为它类似于

{_,tbs_cert} = tuple,
validity = :TBSCertificate(tbs_cert, :Validity),

但是我无法测试它。 'Validity'记录的定义是:

'Validity'{ 
      notBefore, % time()
      notAfter   % time()
     }.

答案 1 :(得分:1)

我会做类似的事情:

with {:Certificate, cert} <- tuple,
     [_, _, _, _, {:Validity, v1, v2} | _] <- Tuple.to_list(cert),
do: {v1, v2}
%⇒ {{:utcTime, '160428162930Z'}, {:utcTime, '170528162930Z'}}

答案 2 :(得分:1)

您可以从public_key.hrl

中提取记录信息
require Record
Record.defrecord :certificate Record.extract(:Certificate, from_lib: "public_key/include/public_key.hrl")
Record.defrecord :TBSCertificate Record.extract(:TBSCertificate, from_lib: "public_key/include/public_key.hrl")
Record.defrecord :validity Record.extract(:Validity, from_lib: "public_key/include/public_key.hrl")

然后你可以写模式匹配

certificate(tbsCertificate: TBSCert) = Tuple,
TBSCertificate(Validity: valid) = TBSCert,
validity(notBefore: from, notAfter: to) = valid,

我不知道Elixir是否足以知道这是否会起作用

certificate(tbsCertificate: TBSCertificate(Validity: validity(notBefore: from, notAfter: to))) = Tuple,