`x`

is a matrix 5x5 of tuples. How can I filter the tuples where the sum of their elements is 6?

```
numbers = [1,2,3,4,5]
x = collect(Iterators.product(numbers, numbers))
```

`x`

is a matrix 5x5 of tuples. How can I filter the tuples where the sum of their elements is 6?

```
numbers = [1,2,3,4,5]
x = collect(Iterators.product(numbers, numbers))
```

Maybe

```
julia> x = collect(Iterators.product(numbers, numbers))
5Ă—5 Matrix{Tuple{Int64, Int64}}:
(1, 1) (1, 2) (1, 3) (1, 4) (1, 5)
(2, 1) (2, 2) (2, 3) (2, 4) (2, 5)
(3, 1) (3, 2) (3, 3) (3, 4) (3, 5)
(4, 1) (4, 2) (4, 3) (4, 4) (4, 5)
(5, 1) (5, 2) (5, 3) (5, 4) (5, 5)
julia> (x -> sum(x) .== 6).(x)
5Ă—5 BitMatrix:
0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
0 1 0 0 0
1 0 0 0 0
```

?

1 Like

OK. But how can filter the tuples that have value `1`

? Like (1, 5), (2, 4), â€¦

I tried to use:

`y = filter((x -> sum(x) .== 6 .x), x)`

but I got an error.

```
julia> x = [ (1,2) (2,4)
(1,1) (1,5) ]
2Ă—2 Matrix{Tuple{Int64, Int64}}:
(1, 2) (2, 4)
(1, 1) (1, 5)
julia> filter(t -> sum(t) == 6, x)
2-element Vector{Tuple{Int64, Int64}}:
(2, 4)
(1, 5)
```

1 Like

@leandromartinez98 Sorry, your solution gives an error.

I donâ€™t understand why the complete solution gives an error:

```
numbers = [1,2,3,4,5]
x = collect(Iterators.product(numbers, numbers))
y = filter(t -> sum(t) == 6, x)
```

It doesnâ€™t here, just copying and pasting your code:

```
julia
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.6.2 (2021-07-14)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> numbers = [1,2,3,4,5]
5-element Vector{Int64}:
1
2
3
4
5
julia> x = collect(Iterators.product(numbers, numbers))
5Ă—5 Matrix{Tuple{Int64, Int64}}:
(1, 1) (1, 2) (1, 3) (1, 4) (1, 5)
(2, 1) (2, 2) (2, 3) (2, 4) (2, 5)
(3, 1) (3, 2) (3, 3) (3, 4) (3, 5)
(4, 1) (4, 2) (4, 3) (4, 4) (4, 5)
(5, 1) (5, 2) (5, 3) (5, 4) (5, 5)
julia> y = filter(t -> sum(t) == 6, x)
5-element Vector{Tuple{Int64, Int64}}:
(5, 1)
(4, 2)
(3, 3)
(2, 4)
(1, 5)
julia>
```

3 Likes

If you `filter`

, what kind of shape do you expect the object to have? Itâ€™s a matrix, what does it mean to just get rid of elements in the matrix?

Sorry, youâ€™re right. I must have done something wrong.

It is OK in the REPL but in Vscode gives the error `MethodError: objects of type Int64 are not callable`

.

Youâ€™re right. But I am only interested in some elements of the matrix and I want to list them.

FWIW, if you donâ€™t care of a matrix shape and only want the tuples which give the sum 6, then you may rewrite your code without `collect`

ing the product:

```
julia> numbers = 1:5;
julia> x = Iterators.product(numbers, numbers); # or x = ((k, l) for k in numbers for l in numbers)
julia> ts = [tup for tup in x if sum(tup) == 6]
5-element Vector{Tuple{Int64, Int64}}:
(5, 1)
(4, 2)
(3, 3)
(2, 4)
(1, 5)
```

The same can be written as `ts = collect(Iterators.filter(tup -> sum(tup) == 6, x))`

but doesnâ€™t work for eager `filter`

(looks like `filter`

isnâ€™t defined for lazy iterables).

3 Likes

Here is what I learnt, where an error said some type â€śare not callableâ€ť, there is somewhere in your code you used a function name as variable.

For example:

```
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.4.2 (2020-05-23)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> sum = 6
6
julia> sum([1,2])
ERROR: MethodError: objects of type Int64 are not callable
Stacktrace:
[1] top-level scope at REPL[2]:1
```

1 Like

Thank you. I had a variable called `sum`

in `Vscode`

but not in REPL.

What do you mean for `eager filter`

?

`Base.filter`

is eager, i.e. it produces all the values once called.

`Iterators.filter`

is lazy, i.e. it produces the values one by one on demand.

Because of that, `Base.filter`

is not defined for an arbitrary iterable, only for certain types which are guaranteed to have a finite length. And, as it turns out, it doesnâ€™t work with generators. `Iterators.filter`

works with any iterable because of laziness.

So, this works:

```
nums = (n for n in 1:10)
evens = [n for n in nums if iseven(n)]
```

This stops with an error because `Base.filter`

doesnâ€™t work with generators (because they potentially may produce an infinite sequence):

```
filter(iseven, nums)
```

3 Likes

FWIW, some benchmarks with the classical Matlab-like alternative:

```
using BenchmarkTools
f(x,n) = x[sum.(x) .== n]
g(x,n) = filter(t -> sum(t) == n, x)
numbers = 1:100
x = collect(Iterators.product(numbers, numbers))
n = 100
f(x,n) == g(x,n) # true
@btime f($x,$n) # 4.4 ÎĽs (4 allocations: 7.3 KiB)
@btime g($x,$n) # 8.7 ÎĽs (3 allocations: 156.3 KiB)
```