Php 有没有一种优雅的方法可以将结构简化为一个简单的数组?
这是:Php 有没有一种优雅的方法可以将结构简化为一个简单的数组?,php,data-structures,Php,Data Structures,这是: $s=array('etc'=>'etc','fields'=> 排列( 0=>数组( 'name'=>'year','description'=>'year of…','type'=>'integer', ), 1=>数组( 'name'=>'label','description'=>'office short name',键入'=>'string', ), 2=>数组( “名称”=>“xx”,“说明”=>“xx…”,“类型”=>“字符串”, ) )); 以下是一种非优雅的方式(或
$s=array('etc'=>'etc','fields'=>
排列(
0=>数组(
'name'=>'year','description'=>'year of…','type'=>'integer',
),
1=>数组(
'name'=>'label','description'=>'office short name',键入'=>'string',
),
2=>数组(
“名称”=>“xx”,“说明”=>“xx…”,“类型”=>“字符串”,
)
));
以下是一种非优雅的方式(或“不那么优雅的方式”)将大数组简化为只包含一列的简单数组:
$fields=array();
foreach($r形式的struts['resources'][0]['schema']['fields']
$fields[]=$r['name'];
这是可行的,但是否可以只使用一条指令就实现同样的功能?可能使用类似于array\u reduce()
,但我不知道如何使用
以下是其他典型的“优雅PHP问题”:
$fieldsByName=array();
foreach($r形式的struts['resources'][0]['schema']['fields']
$fields[$r['name']]=数组(
'description'=>r$r['description'],
'type'=>r$r['type']
);
有PHP替代方案吗?这里的想法是使用关键字(示例中的name
)作为数组键,其他元素作为常规字段,因此,通用的非优雅算法是
$fieldsByName=array();
foreach($r形式的struts['resources'][0]['schema']['fields']{
$key=$r['name'];
未结算($r['name']);
$fields[$key]=$r;
}
您可以使用将键name
的所有值提取到另一个数组中
$names = array_column($strut['resources'][0]['schema']['fields'], 'name');
您可以通过以下功能放置阵列:
function flatten(array $array) {
$return = array();
array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
return $return;
}
它将只产生一个由多维数组的值组成的文本序列,如下所示
Array
(
[0] => etc
[1] => year
[2] => Year of ...
[3] => integer
[4] => day
[5] => Day of the ...
[6] => string
[7] => xx
[8] => Xx ...
[9] => string
)
然后,正如您知道的原始结构一样,您可以根据需要解析它。4ex:每三个值可以是新的assoc数组的键值,该键值包含具有前两个值的数组的数组..,或者如您所愿
array_列是第一个合乎逻辑的声明,这并不奇怪。根据数据的规范化程度以及出现此问题的频率,您可以围绕数据实现一个类。您可以使用和使更改完全透明,并且可以实现帮助器方法来隐藏获取数据的复杂性 以下是一个仅使用ArrayAccess的示例:
class Strut implements ArrayAccess {
private $data;
private $fieldsByName = null;
public function __construct($data) {
$this->data = $data;
}
public function fieldsByName() {
//If the result has not already been computed
if($this->fieldsByName === null) {
$this->fieldsByName = array();
foreach($this->data['resources'][0]['schema']['fields'] as $r) {
$this->fieldsByName[ $r['name'] ] = array(
'description' =>$r['description'],
'type' =>$r['type']
);
}
}
return $this->fieldsByName;
}
/**
* ArrayAccess Methods
*/
public function offsetSet($offset, $value) {
$this->data[$offset] = $value;
}
public function offsetExists($offset) {
return isset( $this->data[$offset] );
}
public function offsetUnset($offset) {
unset( $this->data[$offset] );
}
public function offsetGet($offset) {
return isset( $this->data[$offset] ) ? $this->data[$offset] : null;
}
}
使用上面的代码,您应该能够访问数据,但您也可以选择在一个漂亮的容器中定义其他访问器。请注意,您还必须实现迭代器接口才能对数据进行foreach
这并没有解决底层实现的“优雅”问题(其他解决方案在这方面做得很好),但这种方法完全隐藏了复杂性。我同意你的观点,我们应该简化这个问题,就像我们需要主数组中所有的子数组一样,主数组中的“name”是一个键谢谢,你快速准确(!)。。。第二个问题有什么好的线索吗?@PeterKrauss第二个问题需要更多的函数调用……没有什么内置的东西可以解决这个问题。但是一个好的单行程序应该是
$fields=array\u combine(array\u column($your\u array,'name')),array\u map(function($array){return array\u diff\u key($array,[“name”=>1]),$your\u array))代码>-是的…你需要通过foreach或array_map在数组上迭代…这不重要。没有任何内置功能可以获取没有特定键的数组(比如array_列,只是它不会返回该索引的所有内容,而是返回没有该索引的所有内容)。在这种情况下,使用foreach会更好…@bwoebi,谢谢(!),也许Python有比PHP更优雅的东西:-)是的,一些foreach
与“array\u数组的组合、array的列、array的映射、array\u diff\u键”相比可能更优雅。。。它是PHP。。。您的解决方案没有未设置($r['name'])
是很好的(!),可能对其他读者有用:$x0=array\u组合(array\u列($strub['x'][0],'name')、array\u diff\u键($strub['x'][0],'name'=>1])
很好的线索(!),您能用(解决)我的$fieldsByName
问题来说明解决方案吗?是的,“隐藏复杂性”在库或框架中也是一个好主意,但我的第一个兴趣是PHP内置解决方案(请参见array\u column()
!)…因此,如果PHP没有解决方案(您有解决第二个问题的方法吗?),那么我们必须求助于库,按照您的建议用优雅的类表示。