code: public function slice(ItemInterface $item, $offset, $length = null)
      {
          $names = array_keys($item->getChildren());
          if ($offset instanceof ItemInterface) {
              $offset = $offset->getName();
          }
          if (!is_numeric($offset)) {
              $offset = array_search($offset, $names);
          }
  
          if (null !== $length) {
              if ($length instanceof ItemInterface) {
                  $length = $length->getName();
              }
              if (!is_numeric($length)) {
                  $index = array_search($length, $names);
                  $length = ($index < $offset) ? 0 : $index - $offset;
              }
          }
  
          $slicedItem = $item->copy();
          $children = array_slice($slicedItem->getChildren(), $offset, $length);
          $slicedItem->setChildren($children);
  
          return $slicedItem;
      }
docs: Get slice of menu as another menu.
  
  If offset and/or length are numeric, it works like in array_slice function:
  
  If offset is non-negative, slice will start at the offset.
  If offset is negative, slice will start that far from the end.
  
  If length is null, slice will have all elements.
  If length is positive, slice will have that many elements.
  If length is negative, slice will stop that far from the end.
  
  It's possible to mix names/object/numeric, for example:
  slice("child1", 2);
  slice(3, $child5);
  Note: when using a child as limit, it will not be included in the returned menu.
  the slice is done before this menu.
  
  @param ItemInterface $item
  @param mixed         $offset Name of child, child object, or numeric offset.
  @param mixed         $length Name of child, child object, or numeric length.
  
  @return ItemInterface