给定一个数组数组,我需要确保每个数组的长度都与第一个数组相同。
我有一个应该将矩阵线转换为列的函数。
Original Result
1,2,3 1,4,7
4,5,6 2,5,8
7,8,9 3,6,9
我使用array_map
实现了它:
<?php
$items = array_map(function (...$items) {
return $items;
}, ...$values);
当数组比第一个数组短时我需要抛出LengthException
。
理想的解决方案是将第一个元素的长度存储在array_map之外,并将其与array_map
迭代的当前项的长度进行比较,如下所示:
<?php
$expectedLength = count(reset($values));
$items = array_map(function (...$items) {
$length = count($items);
if ($length !== $expectedLength) {
throw new LengthException("Element size differs ({$length} should be {$expectedLength})");
}
return $items;
}, ...$values);
从PHP手册:
通常在使用两个或多个数组时,它们的长度应相等,因为回调函数与相应的元素并行应用。如果数组的长度不等,则较短的数组将使用空元素进行扩展,以匹配最长的数组。
可悲的是,较短的数组将填充空元素。
由于原始数组可能有空元素,因此我没有其他方法可以测试数组最初是否比第一个短。
我必须在array_map
之前对其进行测试,并且我不相信这是一个很好的解决方案:
<?php
$expectedLength = count(reset($values));
$diffLength = count(array_intersect_key(...$values));
if ($diffLength !== $expectedLength) {
throw new LengthException("Element size differs ({$diffLength} should be {$expectedLength})");
}
$items = array_map(function (...$items) {
return $items;
}, ...$values);
你能帮我找到更好的方法吗?我想在迭代中做到这一点,但如果你找到一种更好的方法来查找迭代前我们是否有一个不同长度的元素(我不想使用array_intersect_key
),那么& #39;也好。
答案 0 :(得分:0)
您可以通过小幅调整来保持理想的解决方案:
array_map(function (...$items) {
$nonNullItems = array_filter(
$items,
function ($item) { return $item !== null }
);
$length = count($nonNullItems);
if ($length !== $expectedLength) {
throw new LengthException(
"Element size differs ({$length} should be {$expectedLength})"
);
}
return $items;
}
请注意这个补充:
array_filter($items, function ($item) { return $item !== null});
它将过滤掉null(但不是0或.0)的项目中的所有元素。
编辑:我不确定,但array_filter($items)
也可以正常工作,但我不确定如果没有回调空或空项目被解雇,所以上面确保只有null是驳回。
答案 1 :(得分:0)
代码:(Demo)
$arrays=[
[['a','b','c'],['d','e','f'],['g','h','i']], // test array #1: no missing elements
[['a','b','c'],['d','e','f'],['g','h']], // test array #2: missing element i
[['a','b','c'],['d','e'],['g','h','i']], // test array #3: missing element f
[['a','b'],['d','e','f'],['g','h','i']], // test array #4: missing element c
[['a','b','c'],['d','e','f'],['g','h',NULL]], // test array #5: NULL on i
];
// find non-specific imbalance using COUNT_RECURSIVE
foreach($arrays as $i=>$a){ // running 5 separate tests
echo "Test #$i:\n";
if(($originalsize=sizeof($a,1))===($rotatedsize=sizeof(array_map(function(){return func_get_args();},...$a),1))){
echo "@$i originalsize ($originalsize) = rotatedsize ($rotatedsize)\n";
}else{
echo "@$i originalsize ($originalsize) DOES NOT EQUAL rotatedsize ($rotatedsize)\n";
}
}
echo "\n\n---\n\n";
// Find specific subarray imbalances using COUNT
foreach($arrays as $i1=>$a){ // running 5 separate tests
echo "Test #$i1:\n";
$firstsize=sizeof($a[0]);
foreach(array_slice($a,1,null,true) as $i2=>$others){
if($firstsize==($othersize=sizeof($others))){
echo "The first size ($firstsize) = subarray $i2 size ($othersize)\n";
}else{
echo "The first size ($firstsize) DOES NOT EQUAL subarray $i2 size ($othersize)\n";
}
}
echo "\n";
}
输出:
Test #0:
@0 originalsize (12) = rotatedsize (12)
Test #1:
@1 originalsize (11) DOES NOT EQUAL rotatedsize (12)
Test #2:
@2 originalsize (11) DOES NOT EQUAL rotatedsize (12)
Test #3:
@3 originalsize (11) DOES NOT EQUAL rotatedsize (12)
Test #4:
@4 originalsize (12) = rotatedsize (12)
---
Test #0:
The first size (3) = subarray 1 size (3)
The first size (3) = subarray 2 size (3)
Test #1:
The first size (3) = subarray 1 size (3)
The first size (3) DOES NOT EQUAL subarray 2 size (2)
Test #2:
The first size (3) DOES NOT EQUAL subarray 1 size (2)
The first size (3) = subarray 2 size (3)
Test #3:
The first size (2) DOES NOT EQUAL subarray 1 size (3)
The first size (2) DOES NOT EQUAL subarray 2 size (3)
Test #4:
The first size (3) = subarray 1 size (3)
The first size (3) = subarray 2 size (3)