获取对象数组的偏移邻居

时间:2017-08-04 22:57:10

标签: php arrays collections

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;给我带来麻烦。

1 个答案:

答案 0 :(得分:0)

看看:https://3v4l.org/5Gt7B

$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(", ") + "]"
  );
}