В этом потоке я задал вопрос о том, как получить N-соседей массива, имеющих заданное начальное смещение и ограничение для поиска. Например:
Рассмотрение коллекции из 5 объектов stdClass для упрощения (см. Ниже):
Если задано limit
2 и начальное смещение 3 , процедура должна возвращать объект со смещением 3
, два других объекта перед ним и только один после него, иначе он выйдет за пределы диапазона.
Если определено limit
3 и начальное смещение 0 , подпрограмма должна вернуть первый объект и три других объекта после него. Ничего другого до первого, потому что, очевидно, иначе он выходил бы за пределы диапазона.
Оба решения, представленные @mickmackusa и @Andreas, решили проблему, но я закончил голосование за @ mickmackusa просто потому, что это быстрее, и потому, что я не так разбираюсь в колдовстве @ 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] ); }
Угадайте, что стоит упомянуть, что в производстве этот Object не будет простым stdClass, возможно, не имеет определенного интерфейса, и ничего подобного.
Еще раз, я не копирую другие решения здесь, чтобы иметь собственный игровой код plug n для моего собственного. Я как бы расширяю мою тему, чтобы сузить проблему до более конкретного сценария.
Я сделал попытку, которая, по сути, решила половину проблемы. Вторая часть – это то, что «дает мне неприятности.
Посмотрите: 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) );
Обратите внимание, что аргумент 3 array_slice
не является индексом: 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(", ") + "]" ); }