我正在为cPanel创建一个Perl插件,该插件必须获取用户帐户中的所有域并将其显示在HTML select
字段中。最初,我是一名PHP开发人员,所以我很难理解Perl的一些逻辑。我知道cPanel插件也可以用PHP编写,但对于这个插件,我只限于Perl。
这是我从cPanel获取数据的方式:
my @user_domains = $cpliveapi->uapi('DomainInfo', 'list_domains');
@user_domains = $user_domains[0]{cpanelresult}{result}{data};
这就是使用print Dumper @user_domains
:
$VAR1 = {
'addon_domains' => ['domain1.com', 'domain2.com', 'domain3.com'],
'parked_domains' => ['parked1.com', 'parked2.com', 'parked3.com'],
'main_domain' => 'main-domain.com',
'sub_domains' => ['sub1.main-domain.com', 'sub2.main-domain.com']
};
我希望数据看起来像这样(感谢@simbabque):
@domains = qw(domain1.com domain2.com domain3.com main-domain.com parked1.com parked2.com parked3.com);
所以,我想排除sub_domains
并将其他人合并到一个单维数组中,这样我就可以用一个循环遍历它们。过去几天我一直在努力,听起来这是一个非常简单的任务,但我无法绕过它。
答案 0 :(得分:1)
这不符合你的想法。 {}
是匿名哈希构造函数,所以你要创建一个带有哈希的1元素数组。
你可能想要:
use Data::Dumper;
my %user_domains = (
'addon_domains' => ['domain1.com', 'domain2.com', 'domain3.com'],
'parked_domains' => ['parked1.com', 'parked2.com', 'parked3.com'],
'main_domain' => 'main-domain.com',
'sub_domains' => ['sub1.main-domain.com', 'sub2.main-domain.com'],
);
print Dumper \%user_domains;
此时,“其他”数组元素可以通过双循环迭代:
foreach my $key ( keys %user_domains ) {
if ( not ref $user_domains{$key} ) {
print $user_domains{$key},"\n";
next;
}
foreach my $domain ( @{$user_domains{$key}} ) {
print $domain,"\n";
}
}
或者如果你真的想要'压扁'你的哈希:
my @flatten = map { ref $_ : @$_ ? $_ } values %user_domains;
print Dumper \@flatten;
(您需要ref
测试,因为没有它,非数组main-domain
将无法正常工作)
因此,为了保持一致性,您可能会更好:
my %user_domains = (
'addon_domains' => ['domain1.com', 'domain2.com', 'domain3.com'],
'parked_domains' => ['parked1.com', 'parked2.com', 'parked3.com'],
'main_domain' => ['main-domain.com'],
'sub_domains' => ['sub1.main-domain.com', 'sub2.main-domain.com'],
);
答案 1 :(得分:1)
你需要这样的东西
如果您发现<?xml version="1.0"?>
<!-- dpcontrols\UseIList.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
initialize="initData();">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.collections.*;
// The data provider is an Array of Strings
public var myArray:Array = ["AZ", "MA", "MZ", "MN", "MO", "MS"];
// Declare an ArrayList that represents the Array.
[Bindable]
public var myAL:ArrayList;
//Initialize the ArrayList.
public function initData():void {
myAL = new ArrayList(myArray);
}
// The function to change the collection, and therefore
// the Array.
public function changeCollection():void {
// Get the original collection length.
var oldLength:int=myAL.length;
// Remove the invalid first item, AZ.
var removedItem:String=String(myAL.removeItemAt(0));
// Add ME as the second item. (ILists used 0-based indexing.)
myAL.addItemAt("ME", 1);
// Add MT at the end of the Array and collection.
myAL.addItem("MT");
// Change the third item from MZ to MI.
myAL.setItemAt("MI", 2);
// Get the updated collection length.
var newLength:int=myAL.length;
// Get the index of the item with the value ME.
var addedItemIndex:int=myAL.getItemIndex("ME");
// Get the fifth item in the collection.
var index4Item:String=String(myAL.getItemAt(4));
// Display the information in the TextArea control.
ta1.text="Start Length: " + oldLength + ". New Length: " +
newLength;
ta1.text+=".\nRemoved " + removedItem;
ta1.text+=".\nAdded ME at index " + addedItemIndex;
ta1.text+=".\nThe item at index 4 is " + index4Item + ".";
// Show that the base Array has been changed.
ta1.text+="\nThe base Array is: " + myArray.join();
}
]]>
</fx:Script>
<s:ComboBox id="myCB" dataProvider="{myAL}"/>
<s:TextArea id="ta1" height="75" width="300"/>
<s:Button label="rearrange list" click="changeCollection();"/>
</s:Application>
的副本不包含List::Util
,那么您可以升级模块或使用此定义
uniq
从您的转储中,sub uniq {
my %seen;
grep { not $seen{$_}++ } @_;
}
调用返回对哈希的引用。这进入uapi
,然后深入到结构中,将$cp_response
哈希引用提取到data
$data
从哈希中删除子域信息。
您想要的列表是delete
引用的哈希的值,因此我将其提取出来。如果列表中有多个域,则这些值是对字符串的引用,如果只有一个域,则为简单字符串
$data
通过取消引用数组引用或直接传递字符串,将所有域名转换为单个列表。这就是map
正在做的事情。 FInally ref() ? @$_ : $_
删除多次出现的同名
uniq
use List::Util 'uniq';
my $cp_response = $cpliveapi->uapi('DomainInfo', 'list_domains');
my $data = $cp_response->{cpanelresult}{result}{data};
delete $data->{sub_domains};
my @domains = uniq map { ref() ? @$_ : $_ } values %$data;