2012-04-01 3 views
3

임의로 중첩 된 데이터 구조가 주어지면 그 안에있는 모든 요소가 표준화 된에 따라 모든 요소가 모든 요소에 적용되도록 새 데이터 구조를 만들 수 있습니까? 요소의 유형에 따라 달라집니다. 예를 들어, 나는Perl 데이터 구조의 각 요소에 다른 함수 적용

$data = { 
    name => 'some one', 
    date => '2010-10-10 12:23:45', 
    sale => [34, 22, 65], 
    cust => { 
     name => 'Jimmy', 
     addr => '1 Foobar Way', 
     amnt => 452.024, 
     item => ['books', 'pens', 'post-it notes'] 
    } 
} 

가있을 수 있습니다 나는, UTC 날짜 시간에 대한 모든 날짜, 모든 정수의 제곱을 찾을 수있는 모든 실수를 반올림 1을 추가하고, 그래서 대문자로 모든 텍스트 값을 변환 할 에. 사실, 요소의 유형에 따라 각 요소에 다른 기능을 적용하려고합니다.

실제로 데이터는 데이터베이스 쿼리를 통해 도착할 수 있습니다.이 경우 데이터는 이미 Perl 데이터 구조이거나 JSON 객체로 시작될 수 있습니다.이 경우 JSON::from_json을 사용하여 Perl 데이터로 변환 할 수 있습니다 구조. 아이디어가 값 형식을 기반으로 데이터 구조의 모든 값을 표준화하고 Perl 데이터 구조를 다시 JSON 개체로 뱉어 버리는 것입니다.

나는 the answers to executing a function on every element of a data structure을 읽고 Data :: Rmap이 그 트릭을 수행 할 수 있다고 생각하지만 어떻게되는지 알아낼 수 없습니다. 에 대해서도 Rmap처럼 작동합니다. 값은이 아닙니다.

+1

질문은 무엇인가 : 코멘트에 대한 질문에 대해서는

use Data::Rmap qw(rmap); rmap { $_ = transform($_); } $data; 

? –

+0

설명이 추가되었습니다. – punkish

답변

2

당신이 언급 한 Data::Rmap을 사용하면 매우 간단합니다.

use Data::Rmap qw(rmap); 
use Scalar::Util qw(looks_like_number); 

# Transforms $_ in place. 
sub transform { 
    if (looks_like_number($_)) { 
     if (...) { 
     $_ *= 2; 
     } 

     $_ = 0+$_; # Makes it look like a number to JSON::XS 
    } else { 
     ... 
    } 
} 

&rmap(\&transform, $data); 
+0

예, 거의 작동합니다. 그것은 모든 수를 인용하여 문자열처럼 취급하는 것 같습니다. 그래서 문자열 변환은 잘 작동하지만 숫자는 영향을받지 않습니다. 'if ($ data = ~/\ d + /) {return $ data * 2; }', 나는 ** 34 ** ** 대신 ** 68 ** – punkish

+0

@ punkish, 아니, * 당신 *을 문자열로 취급하고 있습니다. 일치 연산자는 문자열과 일치합니다. – ikegami

+0

흠 ... 나는 그걸 몰랐다. 그렇다면 문자열을 문자열로 유지하면서 숫자가 숫자로 취급되고 문자열로 강제 변환되지 않도록하려면 어떻게해야합니까? 나는 34 ** ** (** 68 **로 변환) 또는 ** 35.03 ** (** 36 ** **로 변환) ** 34 ** ** 및 * * '35 .03 '** ** 혼자. – punkish

관련 문제