# A view of a Cartesian-product collection over two collections.

A Cartesian product over two collections is just a collection of pairs. Therefore, this view contains all the pairs of elements constructed by associating each element of the first collection to each element of the second collection.

However the view is memory-efficient and the pairs are created only when needed.

A simple Cartesian product

``````var c1 = [1,2]
var c2 = ["a","b","c"]
var c12 = new Cartesian[Int,String](c1, c2)
assert c12.length    == 6
assert c12.join(";") == "(1,a);(1,b);(1,c);(2,a);(2,b);(2,c)"``````

Note: because it is a view, changes on the base collections are reflected on the view.

E.g. c12 is a view on c1 and c2, so if c1 changes, then c12 "changes".

``````assert c2.pop        == "c"
assert c12.length    == 4
assert c12.join(";") == "(1,a);(1,b);(2,a);(2,b)"``````

Cartesian objects are collections, so can be used to build another Cartesian object.

``````var c3 = [1000..2000[
var c123 = new Cartesian[Pair[Int,String],Int](c12, c3)
assert c123.length   == 4000``````

All methods of Collection are inherited, it is so great!

E.g. search elements?

``````var p12 = new Pair[Int,String](2,"b")
assert c12.has(p12)      == true
var p123 = new Pair[Pair[Int, String], Int](p12, 1500)
var p123bis = new Pair[Pair[Int, String], Int](p12, 0)
assert c123.has(p123)    == true
assert c123.has(p123bis) == false``````

### Introduced properties

##### fun ce: Collection[E]

cartesian :: Cartesian :: ce

The first collection
##### protected fun ce=(ce: Collection[E])

cartesian :: Cartesian :: ce=

The first collection
##### fun cf: Collection[F]

cartesian :: Cartesian :: cf

The second collection
##### protected fun cf=(cf: Collection[F])

cartesian :: Cartesian :: cf=

The second collection
##### init defaultinit(ce: Collection[E], cf: Collection[F])

cartesian :: Cartesian :: defaultinit

##### fun swap: Cartesian[F, E]

cartesian :: Cartesian :: swap

Returns a new Cartesian where the first collection is the second.

### Redefined properties

##### redef type SELF: Cartesian[E, F]

cartesian \$ Cartesian :: SELF

Type of this instance, automatically specialized in every class
##### redef fun iterator: Iterator[Pair[E, F]]

cartesian \$ Cartesian :: iterator

Get a new iterator on the collection.
##### redef fun length: Int

cartesian \$ Cartesian :: length

Number of items in the collection.

## All properties

##### fun !=(other: nullable Object): Bool

core :: Object :: !=

Have `self` and `other` different values?
##### fun ==(other: nullable Object): Bool

core :: Object :: ==

Have `self` and `other` the same value?
##### type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
##### type CONCURRENT: ConcurrentCollection[E]

core :: Collection :: CONCURRENT

Type of the concurrent variant of this collection
##### type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
##### fun ce: Collection[E]

cartesian :: Cartesian :: ce

The first collection
##### protected fun ce=(ce: Collection[E])

cartesian :: Cartesian :: ce=

The first collection
##### fun cf: Collection[F]

cartesian :: Cartesian :: cf

The second collection
##### protected fun cf=(cf: Collection[F])

cartesian :: Cartesian :: cf=

The second collection
##### protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by `get_class` to create the specific class.
##### fun class_name: String

core :: Object :: class_name

The class name of the object.

core :: Collection :: combinations

All `r`-length combinations on self (in same order) without repeated elements.

core :: Collection :: combinations_with_replacement

All `r`-length combination on self (in same order) with repeated elements.
##### fun count(item: nullable Object): Int

core :: Collection :: count

How many occurrences of `item` are in the collection?
##### init defaultinit(ce: Collection[E], cf: Collection[F])

cartesian :: Cartesian :: defaultinit

##### init defaultinit

core :: Object :: defaultinit

##### init defaultinit

core :: Collection :: defaultinit

##### fun first: E

core :: Collection :: first

Return the first item of the collection
##### fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of `self`.
##### fun has(item: nullable Object): Bool

core :: Collection :: has

Is `item` in the collection ?
##### fun has_all(other: Collection[nullable Object]): Bool

core :: Collection :: has_all

Does the collection contain at least each element of `other`?
##### fun has_any(other: Collection[nullable Object]): Bool

core :: Collection :: has_any

Does the collection contain at least one element of `other`?
##### fun has_exactly(other: Collection[nullable Object]): Bool

core :: Collection :: has_exactly

Does the collection contain exactly all the elements of `other`?
##### fun has_only(item: nullable Object): Bool

core :: Collection :: has_only

Is the collection contain only `item`?
##### fun hash: Int

core :: Object :: hash

The hash code of the object.
##### init init

core :: Object :: init

##### fun inspect: String

core :: Object :: inspect

Developer readable representation of `self`.

Return "CLASSNAME:#OBJECTID".
##### fun is_empty: Bool

core :: Collection :: is_empty

Is there no item in the collection?
##### intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if `self` and `other` are the same instance (i.e. same identity).
##### fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is `self` the same as `other` in a serialization context?
##### intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if `self` and `other` have the same dynamic type.
##### abstract fun iterator: Iterator[E]

core :: Collection :: iterator

Get a new iterator on the collection.
##### fun join(separator: nullable Text, last_separator: nullable Text): String

core :: Collection :: join

Concatenate and separate each elements with `separator`.
##### fun length: Int

core :: Collection :: length

Number of items in the collection.
##### fun not_empty: Bool

core :: Collection :: not_empty

Alias for `not is_empty`.
##### intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
##### fun output

core :: Object :: output

Display self on stdout (debug only).
##### intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).

core :: Collection :: permutations

All `r`-length permutations on self (all possible ordering) without repeated elements.
##### fun plain_to_s: String

core :: Collection :: plain_to_s

Concatenate elements without separators

core :: Collection :: product

Cartesian product, over `r` times `self`.
##### fun rand: E

core :: Collection :: rand

Return a random element form the collection
##### fun sample(length: Int): Array[E]

core :: Collection :: sample

Return a new array made of (at most) `length` elements randomly chosen.
##### fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
##### fun swap: Cartesian[F, E]

cartesian :: Cartesian :: swap

Returns a new Cartesian where the first collection is the second.
##### intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the `Sys` class.
##### fun to_a: Array[E]

core :: Collection :: to_a

Build a new array from a collection
##### abstract fun to_concurrent: CONCURRENT

core :: Collection :: to_concurrent

Wraps `self` in a thread-safe collection
##### fun to_counter: Counter[E]

core :: Collection :: to_counter

Create and fill up a counter with the elements of `self.
##### fun to_curlslist: CURLSList

core :: Collection :: to_curlslist

Convert Collection[String] to CURLSList
##### abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

##### fun to_s: String

core :: Object :: to_s

User readable representation of `self`.
##### fun to_shuffle: Array[E]

core :: Collection :: to_shuffle

Return a new array made of elements in a random order.

### Ancestors

##### interface Object

core :: Object

The root of the class hierarchy.

### Parents

##### interface Collection[E: nullable Object]

core :: Collection

The root of the collection hierarchy.

## Class definitions

##### cartesian \$ Cartesian
```# A view of a Cartesian-product collection over two collections.
#
# A Cartesian product over two collections is just a collection of pairs.
# Therefore, this view *contains* all the pairs of elements constructed by associating each
# element of the first collection to each element of the second collection.
#
# However the view is memory-efficient and the pairs are created only when needed.
#
# A simple Cartesian product
# ~~~~
# var c1 = [1,2]
# var c2 = ["a","b","c"]
# var c12 = new Cartesian[Int,String](c1, c2)
# assert c12.length    == 6
# assert c12.join(";") == "(1,a);(1,b);(1,c);(2,a);(2,b);(2,c)" # All the 6 pairs
# ~~~~
#
# Note: because it is a view, changes on the base collections are reflected on the view.
#
# E.g. c12 is a view on c1 and c2, so if c1 changes, then c12 "changes".
# ~~~~
# assert c2.pop        == "c"
# assert c12.length    == 4
# assert c12.join(";") == "(1,a);(1,b);(2,a);(2,b)" # All the 4 remaining pairs
# ~~~~
#
# Cartesian objects are collections, so can be used to build another Cartesian object.
# ~~~~
# var c3 = [1000..2000[
# var c123 = new Cartesian[Pair[Int,String],Int](c12, c3)
# assert c123.length   == 4000
# ~~~~
#
# All methods of Collection are inherited, it is so great!
#
# E.g. search elements?
# ~~~~
# var p12 = new Pair[Int,String](2,"b")
# assert c12.has(p12)      == true
# var p123 = new Pair[Pair[Int, String], Int](p12, 1500)
# var p123bis = new Pair[Pair[Int, String], Int](p12, 0)
# assert c123.has(p123)    == true
# assert c123.has(p123bis) == false
# ~~~~
class Cartesian[E, F]
super Collection[Pair[E,F]]

# The first collection
var ce: Collection[E]

# The second collection
var cf: Collection[F]

redef fun length do return ce.length * cf.length # optional, but so efficient...

redef fun iterator do return new CartesianIterator[E,F](self)

# Returns a new Cartesian where the first collection is the second.
# Because the full collection is virtual, the operation is cheap!
fun swap: Cartesian[F, E] do return new Cartesian[F, E](cf, ce)
end
```
lib/cartesian/cartesian.nit:63,1--123,3