# Filter array of CartesianIndex based on x-value

**URL:** <https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583>\
**Category:** Performance\
**Tags:** question\
**Created:** [December 29, 2020, 7:21pm UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583 "2020-12-29T19:21:51Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![zxjroger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxjroger/32/11826_2.png) [@zxjroger](https://discourse.julialang.org/u/zxjroger)\
**Post date:** [December 29, 2020, 7:21pm UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583/1 "2020-12-29T19:21:51Z")

</div>

I have a vector of Cartesian indexes, for example:

```julia
temp = [CartesianIndex(3, 1), CartesianIndex(2, 2), CartesianIndex(6, 3), CartesianIndex(3, 4), 
        CartesianIndex(1, 5), CartesianIndex(5, 6), CartesianIndex(1, 7), CartesianIndex(1, 8), 
        CartesianIndex(4, 9), CartesianIndex(1, 10), CartesianIndex(2, 11), CartesianIndex(6, 12), 
        CartesianIndex(1, 13)]

```

I would like to split this vector into two vectors. The first vector collects all indexes on the first row, which is

```julia
v1 = [CartesianIndex(1, 5), CartesianIndex(1, 7), CartesianIndex(1, 8), CartesianIndex(1, 10), CartesianIndex(1, 13)]

```

Then, the second vector collects all the remaining indexes. How should I do it? Thank you very much.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 29, 2020, 7:25pm UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583/2 "2020-12-29T19:25:24Z")

</div>

Just write a loop that pushes each element `ind` to one vector or the other based on whether `first(Tuple(ind)) == 1`.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [December 29, 2020, 7:25pm UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583/3 "2020-12-29T19:25:49Z")

</div>

```julia
julia> v1 = [x for x in temp if x.I[1]==1]
5-element Array{CartesianIndex{2},1}:
 CartesianIndex(1, 5)
 CartesianIndex(1, 7)
 CartesianIndex(1, 8)
 CartesianIndex(1, 10)
 CartesianIndex(1, 13)

```

or

```julia
julia> v1 = filter(x->x.I[1]==1, temp)
5-element Array{CartesianIndex{2},1}:
 CartesianIndex(1, 5)
 CartesianIndex(1, 7)
 CartesianIndex(1, 8)
 CartesianIndex(1, 10)
 CartesianIndex(1, 13)

```

---

<div class="post-metadata">

**Author:** ![zxjroger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxjroger/32/11826_2.png) [@zxjroger](https://discourse.julialang.org/u/zxjroger)\
**Post date:** [December 29, 2020, 7:38pm UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583/4 "2020-12-29T19:38:11Z")

</div>

Thanks, this is exactly what I am looking for.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 29, 2020, 8:28pm UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583/5 "2020-12-29T20:28:08Z")

</div>

```julia
function sort1(v)
    v1 = similar(v, 0)
    v2 = similar(v, 0)
    for ind in v
        if first(Tuple(ind)) == 1
            push!(v1, ind)
        else
            push!(v2, ind)
        end
    end
    return v1, v2
end

```

```julia
julia> v1, v2 = sort1(temp);

julia> v1
5-element Array{CartesianIndex{2},1}:
 CartesianIndex(1, 5)
 CartesianIndex(1, 7)
 CartesianIndex(1, 8)
 CartesianIndex(1, 10)
 CartesianIndex(1, 13)

julia> v2
8-element Array{CartesianIndex{2},1}:
 CartesianIndex(3, 1)
 CartesianIndex(2, 2)
 CartesianIndex(6, 3)
 CartesianIndex(3, 4)
 CartesianIndex(5, 6)
 CartesianIndex(4, 9)
 CartesianIndex(2, 11)
 CartesianIndex(6, 12)

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 29, 2020, 8:35pm UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583/6 "2020-12-29T20:35:57Z")

</div>

> [@jling](#):
>
> `x.I[1]`

I know this usage is super common, but I’m always uncomfortable with it. As far as I can tell, the field `I` isn’t actually part of the documented interface of `CartesianIndex`, which means it’s accessing an internal, undocumented field.

Did I miss where this is documented? or if not, why is `x.I` so widespread, when `Tuple(x)` seems more robust and idiomatic?

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [December 29, 2020, 10:10pm UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583/7 "2020-12-29T22:10:14Z")

</div>

This is slower then two filters. So it’s better to just filter or preallocate vectors of the size of original array, assign by index and resize at the end.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 29, 2020, 11:00pm UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583/8 "2020-12-29T23:00:07Z")

</div>

What? How can it be slower than two `filter`s? That’s extremely surprising to me.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [December 30, 2020, 2:51am UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583/9 "2020-12-30T02:51:35Z")

</div>

> [@jling](#):
>
> `[x for x in temp if x.I[1]==1]`

```julia
julia> @btime filter(x->x.I[1]==1, $temp)
  37.096 ns (1 allocation: 288 bytes)

julia> @btime filter(x->first(Tuple(x))==1, $temp)
  38.611 ns (1 allocation: 288 bytes)

julia> @btime sort1($temp)
  69.938 ns (3 allocations: 304 bytes)

```

yeah, `first(Tuple(idx))` is also good

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 30, 2020, 8:35am UTC](https://discourse.julialang.org/t/filter-array-of-cartesianindex-based-on-x-value/52583/10 "2020-12-30T08:35:35Z")

</div>

> [@DNF](#):
>
> What? How can it be slower than two `filter` s? That’s extremely surprising to me.

I guess it’s all about the allocations. `filter` seems to allocate two full-size array, and then resizes them, which is just faster than `push!`, even with `sizehint!`.

Here’s the fastest solution I found, faster than filter:

```julia
function sortnew(v)
    v1, v2 = similar(v), similar(v)
    i0 = i1 = i2 = firstindex(v)
    @inbounds for i in eachindex(v)
        val = v[i]
        v1[i1] = v2[i2] = val
        isone = first(Tuple(val)) == 1
        i1 += isone
        i2 += !isone
    end
    resize!(v1, i1 - i0)
    resize!(v2, i2 - i0)
    return v1, v2
end

```
