def _filtdim(items, shape, dim, nsl):
    normshape = tuple(stop - start for start, stop in shape)
    nsl_type = type(nsl)
    newitems = list()
    num = reduce(operator.mul, normshape[:dim+1])
    size = len(items) // num
    n = normshape[dim]
    if nsl_type is int:
        for i in range(num):
            if i % n == nsl:
                newitems += items[size*i:size*(i+1)]
        newshape = shape[:dim] + shape[dim+1:]
    elif nsl_type is slice:
        for i in range(num):
            if nsl.start <= (i % n) < nsl.stop:
                newitems += items[size*i:size*(i+1)]
        offset = shape[dim][0]
        redim = (offset + nsl.start, offset + nsl.stop)
        newshape = shape[:dim] + (redim, ) + shape[dim+1:]
    else:
        if nsl.size < clog2(n):
            fstr = "expected dim {} select to have >= {} bits, got {}"
            raise ValueError(fstr.format(dim, clog2(n), nsl.size))
        groups = [list() for _ in range(n)]
        for i in range(num):
            groups[i % n] += items[size*i:size*(i+1)]
        for muxins in zip(*groups):
            it = boolfunc.iter_terms(nsl._items)
            xs = [reduce(operator.and_, (muxin, ) + next(it))
                  for muxin in muxins]
            newitems.append(reduce(operator.or_, xs))
        newshape = shape[:dim] + shape[dim+1:]
    return newitems, newshape