获取对象数组的偏移邻居 [英] Get offset neighbors of an array of Objects

查看:68
本文介绍了获取对象数组的偏移邻居的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此线程中,我提出了一个有关如何获取具有用户定义的起始偏移量的数组的N个邻居的问题并限制搜索.例如:

In this thread I raised a question about how to get N-neighbors of an array having user-defined starting offset and limit for the search. E.g:

考虑简化5个stdClass对象的集合(请参见下文):

Considering a Collection of 5 stdClass Objects to simplify (see below):

  • 如果将limit定义为 2 ,并将起始偏移量定义为 3 ,则例程应返回偏移量为3的Object,另外两个在它之前的对象以及在它之后的对象,否则它将超出范围.

  • If defined a limit of 2 and a starting offset of 3, the routine should return the Object at offset 3, the two other Objects before it and only one after it, otherwise it would go out of range.

如果将limit定义为 3 ,并且将起始偏移量定义为 0 ,则例程应返回第一个对象,其后返回其他三个对象.在第一个之前没有什么别的,因为显然,否则它也将超出范围.

If defined a limit of 3 and a starting offset of 0, the routine should return the first Object and the three other Objects after it. Nothing else before the first because, obviously, otherwise it would go out of range as well.

@mickmackusa @mickmackusa的,原因仅仅是它更快且更因为我并不精通 @Andreas 的巫术(对不起,哥们:p)

Both solutions presented by @mickmackusa and @Andreas solved the issue but I ended up voting for @mickmackusa's simply because it's faster and because I'm not that versed in the sorcery @Andreas did there (sorry buddy :p)

嗯,这个问题很难向我解释,所以我用简单的数组简化了它.即使仍然很难理解,这就是为什么我决定将其拆分到另一个线程中的原因,所以:

Well, the question was hard to explain to me so I simplified it with simple arrays. And even though it was still kind of hard to understand, that's why I decided to split this in a different thread, so:

如何检索包含混合内容(特别是对象

我尝试使用此(伪)数据应用两个最新的解决方案,但均未成功:

I tried to apply, without success, both of the most updated solutions with this (fake) data:

$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] );
}

值得一提的是,在生产中这些Object不会是简单的stdClass,可能没有实现特定的接口,也没有类似的东西.

Guess that worth to mention that in production these Object won't be simple stdClass, may not have a specific interface implemented nor anything like that.

再一次,我不会在这里复制其他人的解决方案以拥有自己的即插即用播放代码.我有点扩展了我的另一个主题,以将问题缩小到更具体的情况.

Once again, I'm not copying others' solutions here to have a plug n' play code for my own. I'm kind of extending a different topic of mine to narrow a problem to a more specific scenario.

我做了一次尝试,实际上解决了一半的问题.第二部分是给我带来麻烦的原因.

I did made an attempt which, in fact, solved half of the issue. The second part is what' giving me trouble.

推荐答案

看看: 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个项目.

Note that argument 3 of array_slice is not an index : RTM :-P Argument 2 (index) : $i - min($i, $padding) = shift to the "left" of the ith item until you reach zero. Argument 3 (length) : $padding + 1 + min($i, $padding) = take at least $padding + 1 items.

另一个带有一些图纸的示例:

Another example with some drawings :

$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的第二个参数是索引)

JS version (unlike array_slice, the second argument of slice is an index) :

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

这篇关于获取对象数组的偏移邻居的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆