在this thread中,我提出了一个问题,即如何获得具有用户定义的起始偏移量和搜索限制的数组的N邻居。 E.g:
考虑简化5个stdClass对象的集合(见下文):
如果定义了 2 的limit
和 3 的起始偏移量,则例程应返回偏移量为3
的对象,它之前的另外两个对象,之后只有一个,否则会超出范围。
如果定义了 3 的limit
和 0 的起始偏移量,则例程应返回第一个对象和其他三个对象它。在第一个之前没有别的东西,因为很明显,否则它也会超出范围。
@mickmackusa和@Andreas提供的两个解决方案都解决了这个问题,但我最终投票选择了@mickmackusa's,因为它更快,因为我不是那么精通在巫术@Andreas那里做了(抱歉哥们:p)
嗯,问题很难向我解释,所以我用简单的数组简化了它。即使它仍然有点难以理解,这就是为什么我决定将其拆分为另一个线程,所以:
如何检索具有填充混合内容的数组的相同类型的信息,特别是对象
我试图用这个(假的)数据来应用这两个最新的解决方案,但没有成功:
$std1 = new\stdClass;
$std1 -> name = 'Name #1';
$std2 = new\stdClass;
$std2 -> name = 'Name #2';
$std3 = new\stdClass;
$std3 -> name = 'Name #3';
$std4 = new\stdClass;
$std4 -> name = 'Name #4';
$std5 = new\stdClass;
$std5 -> name = 'Name #5';
$collection = [ $std1, $std2, $std3, $std4, $std5 ];
$offset = rand( 0, 5 );
$limit = rand( 1, 5 );
printf( 'Value at offset #%d: %s<br />', $offset, $collection[ $offset ] -> name );
printf( 'Random limit: %d<br />', $limit );
var_dump( $collection );
var_dump( getNeighborsMickVersion( $collection, $offset, $limit ) );
var_dump( getNeighborsAndreasVersion( $collection, $offset, $limit ) );
function getNeighborsMickVersion( array $collection, $offset = 0, $limit = 1 ) {
return array_intersect_key(
$collection,
array_flip(
range( ( $offset - $limit ), ( $offset + $limit ) )
)
);
}
function getNeighborsAndreasVersion( array $collection, $offset = 0, $limit = 1 ) {
Preg_match("/.{0," . $limit ."}" . chr(65 +$offset) . ".{0," . $limit ."}/", implode("", $collection), $match);
return str_split($match[0] );
}
猜测值得一提的是,在生产中,这些对象不是简单的stdClass,可能没有实现特定的接口,也没有类似的接口。
再一次,我不会抄袭他人&#39;解决方案在这里有一个插头n&#39;为我自己玩代码。我有点扩展我的另一个主题,将问题缩小到更具体的情况。
我做了一次尝试,实际上解决了一半的问题。第二部分是&#39;给我带来麻烦。
答案 0 :(得分:0)
$padding = 6;
$letters = range('A', 'Z');
$i = 25;
$slice = array_slice(
$letters,
$i - min($i, $padding),
$padding + 1 + min($i, $padding)
);
请注意array_slice
的参数3不是索引:RTM :-P参数2(索引):$i - min($i, $padding)
=转移到第i个项目的“左”,直到达到零。参数3(长度):$padding + 1 + min($i, $padding)
=至少取$padding + 1
项。
另一个带有一些图纸的例子:
$i = 1;
$padding = 2;
$letters = range('a', 'z');
$start = $i - min($i, $padding); // = 0
$length = $padding + 1 + min($i, $padding); // = 4
$slice = array_slice($letters, $start, $length);
0 1 2 3 4 5 6 7 ...
[ a | b | c | d | e | f | g | h | ... ]
^ ^
| $i
$start = shift by $padding or as much as possible
0 1 2 3 4 5 6 7 ...
[ a | b | c | d | e | f | g | h | ... ]
$length
<-----> = $padding items
<---------> + the item in the middle
<-------------> + $padding items or as much as possible
JS版本(与array_slice
不同,slice
的第二个参数是索引):
padding = 2;
letters = new Array(27).join(" ").split("");
letters = letters.map((x, i) => (i + 10).toString(36));
indexes = ["-1", " 0", " 1", " 2", "13", "24", "25", "26"];
for (i = 0; i < indexes.length; i++) {
index = parseInt(indexes[i], 10);
s = letters.slice(
index - Math.min(index, padding),
padding + index + 1
);
console.log(
indexes[i],
letters[index] || "/",
"[" + s.join(", ") + "]"
);
}