จะแปลงพารามิเตอร์แบบสอบถามเชิงลึกเป็นโครงสร้างข้อมูล Perl ได้อย่างไร

ฉันเรียนรู้การใช้ Datatables เพื่อวาดตารางแบบไดนามิกบนเว็บไซต์ของฉัน โดยใช้ข้อมูลฝั่งเซิร์ฟเวอร์เป็นแหล่งที่มาของตาราง Datatables ใช้พารามิเตอร์ที่ซับซ้อนในการสืบค้น ซึ่งฉันต้องการแปลงเป็นโครงสร้างข้อมูล Perl ที่เหมาะสม ดังนั้นสตริงการสืบค้นเช่นนี้ (ห่อเป็นบรรทัดเพื่อความชัดเจน):

columns[0][data]=status&
columns[0][name]=&
columns[0][searchable]=true&
columns[0][orderable]=true&
columns[0][search][value]=&
columns[0][search][regex]=false&
columns[1][data]=some&
columns[1][name]=&
columns[1][searchable]=true&
columns[1][orderable]=true&
columns[1][search][value]=&
columns[1][search][regex]=false&
columns[2][data]=title&
columns[2][name]=&
columns[2][searchable]=true&
columns[2][orderable]=true&
columns[2][search][value]=&
columns[2][search][regex]=false

จะกลายเป็นเช่น:

@columns = ( {
    data => 'status',
    name => '',
    searchable => 1,
    orderable => 1,
    search => {
      value => '',
      regex => 0,
    }
  },
  {
    data => 'true',
    name => '',
    searchable => 1,
    orderable => 1,
    search => {
      value => '',
      regex => 0,
    }
  },
  {
    data => 'title',
    name => '',
    searchable => 1,
    orderable => 1,
    search => {
      value => '',
      regex => 0,
    }
  },
);

วิธีที่ดีที่สุดในการบรรลุเป้าหมายคืออะไร?

แก้ไข. นอกจากนี้ ในกรณีนี้ ฉันใช้ CGI.pm เพื่อดึงพารามิเตอร์การสืบค้น ซึ่งทำให้ฉันมีโครงสร้างข้อมูลแบบเรียบ


person w.k    schedule 01.06.2014    source แหล่งที่มา
comment
มีการบูรณาการ Perl สำหรับ DataTables ซึ่งสามารถให้สิ่งที่คุณต้องการ datatables.net/development/server- ด้านข้าง/perl_mvc   -  person KeepCalmAndCarryOn    schedule 02.06.2014
comment
@KeepCalmAndCarryOn: AFAIU สิ่งนี้และ Perl Module Datatables เข้ากันไม่ได้กับ API ใหม่ของ Datatables   -  person w.k    schedule 02.06.2014


คำตอบ (3)


สมมติว่าคุณดึงพารามิเตอร์ออกจากวัตถุ CGI สิ่งต่อไปนี้อาจใช้งานได้:

use strict;
use warnings;

my %params = (
    'columns[0][data]'          => 'status',
    'columns[0][name]'          => '',
    'columns[0][searchable]'    => 'true',
    'columns[0][orderable]'     => 'true',
    'columns[0][search][value]' => '',
    'columns[0][search][regex]' => 'false',
    'columns[1][data]'          => 'some',
    'columns[1][name]'          => '',
    'columns[1][searchable]'    => 'true',
    'columns[1][orderable]'     => 'true',
    'columns[1][search][value]' => '',
    'columns[1][search][regex]' => 'false',
    'columns[2][data]'          => 'title',
    'columns[2][name]'          => '',
    'columns[2][searchable]'    => 'true',
    'columns[2][orderable]'     => 'true',
    'columns[2][search][value]' => '',
    'columns[2][search][regex]' => 'false',
);

my @columns;
while (my ($key, $val) = each %params) {
    next if $key !~ /^columns/;
    my @keys = $key =~ /\[(.*?)\]/g;
    my $ref = $columns[shift @keys] ||= {};
    $ref = $ref->{shift @keys} ||= {} while @keys > 1;
    $ref->{$keys[0]} = $val;
}

use Data::Dump;
dd @columns;

เอาท์พุต:

(
  {
    data => "status",
    name => "",
    orderable => "true",
    search => { regex => "false", value => "" },
    searchable => "true",
  },
  {
    data => "some",
    name => "",
    orderable => "true",
    search => { regex => "false", value => "" },
    searchable => "true",
  },
  {
    data => "title",
    name => "",
    orderable => "true",
    search => { regex => "false", value => "" },
    searchable => "true",
  },
)
person Miller    schedule 01.06.2014

คุณสามารถลองบางอย่างเช่น:

#! /usr/bin/perl

use warnings;
use strict;

my $qs="columns[0][data]=status&columns[0][name]=&columns[0][searchable]=true&columns[0][orderable]=true&columns[0][search][value]=&columns[0][search][regex]=false&columns[1][data]=some&columns[1][name]=&columns[1][searchable]=true&columns[1][orderable]=true&columns[1][search][value]=&columns[1][search][regex]=false&columns[2][data]=title&columns[2][name]=&columns[2][searchable]=true&columns[2][orderable]=true&columns[2][search][value]=&columns[2][search][regex]=false";

my @data=split ("&",$qs);

my @col;

for (@data) {
   my ($val)=/=(.*)$/;
   $_=~s/=.*//;
   my @b=split(/\[(.*?)\]/);
   my @c=@b[grep {$_% 2} 0..$#b];
   if (@c==2) {
      $col[$c[0]]->{$c[1]}=$val;
   } else {
      $col[$c[0]]->{$c[1]}{$c[2]}=$val;
   }
}

หรือใช้ eval สำหรับวิธีแก้ปัญหาทั่วไป:

for (@data) {
   my ($val)=/=(.*)$/;
   $_=~s/=.*//;
   my @b=split(/\[(.*?)\]/);
   my @c=@b[grep {$_% 2} 0..$#b];
   my $cmd='$col[$c[0]]->';
   for my $i (1..$#c) {
      $cmd.='{$c['.$i.']}';
   }
   $cmd.='=$val';
   eval ($cmd);
}
person Håkon Hægland    schedule 01.06.2014

person    schedule
comment
โครงสร้างนี้คืออะไร โดยที่คุณกำหนดให้กับการเรียกใช้ฟังก์ชัน (DiveVal() = ...) - person w.k; 02.06.2014
comment
@w.k: มันเป็นฟีเจอร์ที่ใช้เล็กน้อยที่เรียกว่า lvalue subs; ส่วนย่อยต้องประกาศว่าอนุญาตให้เรียกแบบนั้นได้ มันมีประโยชน์อย่างยิ่งในกรณีเช่นนี้ที่ส่วนย่อยกำลังสร้างคอนเทนเนอร์ใหม่ที่น่าจะถูกกำหนดให้ มี DiveRef ทางเลือกอื่นที่ไม่พิเศษที่คุณจะเรียกว่า ${ DiveRef( ... ) } = $value - person ysth; 02.06.2014