Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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
erlang:从PropList中获取键集的值_List_Loops_Search_Erlang - Fatal编程技术网

erlang:从PropList中获取键集的值

erlang:从PropList中获取键集的值,list,loops,search,erlang,List,Loops,Search,Erlang,我有“难”的道具清单。我需要进入serviceCatalog并遍历它的所有值,直到得到一个名为me J =[{<<"access">>, {[{<<"token">>, {[{<<"issued_at">>,<<"2015-09-12T13:27:38.789879">>}, {<<"expires">>,<<"2

我有“难”的道具清单。我需要进入
serviceCatalog
并遍历它的所有值,直到得到一个名为
me

J =[{<<"access">>,
      {[{<<"token">>,
         {[{<<"issued_at">>,<<"2015-09-12T13:27:38.789879">>},
           {<<"expires">>,<<"2015-09-12T14:27:38Z">>},
           {<<"id">>,<<"fe">>},
           {<<"tenant">>,
            {[{<<"description">>,null},
              {<<"enabled">>,true},
              {<<"id">>,<<"01">>},
              {<<"name">>,<<"service">>}]}},
           {<<"audit_ids">>,[<<"f">>]}]}},
        {<<"serviceCatalog">>,
         [{[{<<"endpoints">>,
             [{[{<<"adminURL">>,<<"http://8.198.99.999:8080">>},
                {<<"region">>,<<"RegionOne">>},
                {<<"internalURL">>,
                 <<"http://8.198.99.999:8080/v1/AUTH_01a"...>>},
                {<<"id">>,<<"30">>},
                {<<"publicURL">>,<<"8.198.99.999:8080/v1/"...>>}]}]},
            {<<"endpoints_links">>,[]},
            {<<"type">>,<<"object-store">>},
            {<<"name">>,<<"my">>}]},
          {[{<<"endpoints">>,
             [{[{<<"adminURL">>,<<"8.198.99.999:8080/v2.0">>},
                {<<"region">>,<<"RegionOne">>},
                {<<"internalURL">>,<<"8.198.99.999:8080/v2.0">>},
                {<<"id">>,<<"4b3f44a5c64b4bd8b10c376c858b"...>>},
                {<<"publicURL">>,<<"8.198.99.999:8080"...>>}]}]},
            {<<"endpoints_links">>,[]},
            {<<"type">>,<<"identity">>},
            {<<"name">>,<<"other">>}]}]},
        {<<"user">>,
         {[{<<"username">>,<<"my">>},
           {<<"roles_links">>,[]},
           {<<"id">>,<<"8">>},
           {<<"roles">>,[{[{<<"name">>,<<"admin">>}]}]},
           {<<"name">>,<<"me">>}]}},
        {<<"metadata">>,
         {[{<<"is_admin">>,0},
           {<<"roles">>,
            [<<"e">>]}]}}]}}]
J=[{,
{[{,
{[{,},
{,},
{,},
{,
{[{,null},
{,没错},
{,},
{,}]}},
{,[]}]}},
{,
[{[{,
[{[{,},
{,},
{,
},
{,},
{,}]}]},
{,[]},
{,},
{,}]},
{[{,
[{[{,},
{,},
{,},
{,},
{,}]}]},
{,[]},
{,},
{,}]}]},
{,
{[{,},
{,[]},
{,},
{,[{[{,}]}]},
{,}]}},
{,
{[{,0},
{,
[]}]}}]}}]
我正在寻找一种很好的方法。 我是这样开始实施的(但看起来还有更优雅的解决方案):

A1=proplist:get_值(,J)。
A=元件(1,A1)。
B=proplist:get_值(,A)。
C=元素(1,B)。
D=proplist:get_值(,C)。

任何建议都是好的

考虑到数据嵌套的深度,一种方法是编写一组递归函数子句,可以找到具有给定键的2元组,而不管其在数据中的级别如何。下面是一个例子:

-module(t).
-export([extract/2]).

extract(Key, Data) ->
    extract(Key, Data, []).
extract(_Key, [], Acc) ->
    Acc;
extract(Key, {Key,_}=KV, Acc) ->
    [KV|Acc];
extract(Key, [{Key,_}=KV|Fields], Acc) ->
    extract(Key, Fields, [KV|Acc]);
extract(Key, [{_,V}|Fields], Acc) when is_tuple(V); is_list(V) ->
    extract(Key, Fields, extract(Key, V, Acc));
extract(Key, Data, Acc) when is_list(Data) ->
    lists:foldl(fun(V, FoldAcc) when is_tuple(V); is_list(V) ->
                        extract(Key, V, FoldAcc);
                   (_, FoldAcc) ->
                        FoldAcc
                end, Acc, Data);
extract(Key, Data, Acc) when is_tuple(Data) ->
    extract(Key, tuple_to_list(Data), Acc).
extract/2
函数只是将其参数和空累加器列表一起传递给
extract/3
extract/3
的条款如下所述:

  • 第一个子句检查数据是否为空列表,如果为空,则返回累加器
  • 第二个子句匹配所需的
    ,作为2元组的第一个元素,并将匹配的元组添加到累加器中
  • 第三个子句匹配所需的
    ,作为列表开头2元组的第一个元素。它将匹配的元组添加到累加器中,并继续从列表的其他元素中提取
  • 第四个子句处理2元组的情况,其中元组中的值要么是列表,要么是元组;如果是,它将尝试从值中提取,然后继续从列表的其余部分提取
  • Data
    是一个与前面的子句已经匹配的列表不匹配的列表时,第五个子句匹配。它折叠列表的所有值,尝试从所有嵌套列表和元组值中提取,并忽略所有其他值
  • Data
    是元组时,第六个也是最后一个子句匹配;它只是将元组转换为一个列表,并递归调用
    extract/3
给定问题中定义的数据
J
,我们可以找到一个具有
键的2元组,如下所示:

1> SCs = t:extract(<<"serviceCatalog">>, J).
[{<<"serviceCatalog">>,
  [{[{<<"endpoints">>,
      [{[{<<"adminURL">>,<<"http://8.198.99.999:8080">>},
         {<<"region">>,<<"RegionOne">>},
         {<<"internalURL">>,
          <<"http://8.198.99.999:8080/v1/AUTH_01a">>},
         {<<"id">>,<<"30">>},
         {<<"publicURL">>,<<"8.198.99.999:8080/v1/">>}]}]},
     {<<"endpoints_links">>,[]},
     {<<"type">>,<<"object-store">>},
     {<<"name">>,<<"my">>}]},
   {[{<<"endpoints">>,
      [{[{<<"adminURL">>,<<"8.198.99.999:8080/v2.0">>},
         {<<"region">>,<<"RegionOne">>},
         {<<"internalURL">>,<<"8.198.99.999:8080/v2.0">>},
         {<<"id">>,<<"4b3f44a5c64b4bd8b10c376c858b">>},
         {<<"publicURL">>,<<"8.198.99.999:8080">>}]}]},
     {<<"endpoints_links">>,[]},
     {<<"type">>,<<"identity">>},
     {<<"name">>,<<"other">>}]}]}]
列表理解遍历所有
元素,从每个元素中提取所有
元组,并检查是否有值为
的元组

不幸的是,示例数据中的
元素没有问题中描述的
{,}
元组,因此上述列表理解结果(结果未显示)中的布尔值为
false
。但是,无论哪种方式,要遍历列表理解的结果,只保留
true
值,但去掉布尔值,这样生成的列表只包含匹配的
元素,我们可以折叠列表。首先,让我们制作一个折叠函数:

3> Fold = fun({SC, true}, Acc) -> [SC|Acc]; (_, Acc) -> Acc end.
#Fun<erl_eval.12.54118792>

同样,由于数据中没有
元素包含
{,}
元组,因此这里的结果列表是空的,但是如果有,我们将从
列表返回它们的值:foldl/3

请澄清问题;您的意思是要查找此数据中具有键
的所有元组,该键的值包含一个值为
{,}
的元组,如果找到
{,}
,是否要返回整个
元组?顺便说一句,如果这是您想要的,请注意您的示例数据不匹配,因为
{,}
仅存在于
{,…}
元组中。
2> [{SC,lists:any(fun({_, V}) -> V == <<"me">> end, t:extract(<<"name">>, SC))} || SC <- SCs].
3> Fold = fun({SC, true}, Acc) -> [SC|Acc]; (_, Acc) -> Acc end.
#Fun<erl_eval.12.54118792>
4> SCBools = [{SC,lists:any(fun({_, V}) -> V == <<"me">> end, t:extract(<<"name">>, SC))} || SC <- SCs].
...
5> lists:foldl(Fold, [], SCBools).
[]