2014-12-11 2 views
0

У меня есть Erlang Couch DB, который представляет объект JSON как так:Erlang - Условно Omit свойство из Couch DB Посмотреть

fun({Doc}) -> 
    Name = couch_util:get_value(<<\"name\">>, Doc), 
    Value = couch_util:get_value(<<\"Value\">>, Doc), 
    Geocode = couch_util:get_value(<<\"geocode\">>, Doc), 
    Emit(
     Name, 
     {[ 
      { <<\"value\">>,Value }, 
      { <<\"geocode\">>, Geocode }    
     ]} 
    ) 
end. 

Проблема в том, что все документы в этой точке зрения не имеют " геокода ". В случае отсутствия геокода, я бы предпочел не показывать его. В псевдокоде, я бы по существу хотел бы, чтобы это ...

Emit(
    Name, 
    {[ 
     { <<\"value\">>,Value }, 
     Geocode != undefined ? { <<\"geocode\">>, Geocode } : null 
    ]} 
); 

Я подозреваю, что это не будет так легко сделать это в Erlang?

До сих пор мое лучшее решение заключается в следующем:

fun({Doc}) -> 
    Name = couch_util:get_value(<<\"name\">>, Doc), 
    Value = couch_util:get_value(<<\"Value\">>, Doc), 
    Geocode = couch_util:get_value(<<\"geocode\">>, Doc), 
    % I think 'couch_util:get_value' returns the atom undefined, if the value doesn't exist. 
    Undefined = undefined, 
    if Geocode /= Undefined -> 
     Emit(
      Name, 
      {[ 
       { <<\"value\">>, Value }, 
       { <<\"geocode\">>, Geocode }    
      ]} 
     ); 
    true -> Emit(Name, {[ { <<\"value\">>, Value } ]}) 
    end; 
end. 

Довольно уверен, что будет один или два синтаксических ошибок там ... пожалуйста, не стесняйтесь указывать их! Но что еще более важно, существует ли более эффективный способ условно удалить значение «геокода» из пролистника/представления?

ответ

2

Что вы пытаетесь сделать, это отфильтровать отсутствующие свойства.

Давайте genererate proplist с list comprehension:

ListOfKeys = [<<"value">>, <<"geocode">>], Proplist = [{Key, couch_util:get_value(Key, Doc)} || Key <- ListOfKeys],

и давайте filter/2 из реквизита с undefined значение:

FilteredProplist = lists:filter( fun ({_Key, undefined}) -> false; % it matches => it's out ({_Key, _Value}) -> true end, Proplist),

Теперь вы можете просто Emit(Name, FilteredProplist).

Кроме того, можно фильтровать их в списке понимания, но это не выглядит ясно:

FilteredProplist = [{Key, Value} || Key <- ListOfKeys, Value <- [couch_util:get_value(Key, Doc)], Value /= undefined]

EDIT: О ... Я думаю, что я пропустил самый важный вопрос: Как писать в erlang?

{[ { <<\"value\">>,Value }, Geocode != undefined ? { <<\"geocode\">>, Geocode } : null ]}

ответ:

{ [{ <<"value">>,Value }] ++ if Geocode /= undefined -> [{ <<"geocode">>, Geocode }]; true -> [] end }

Смежные вопросы