pub fn join_step(mut itemsets: Vec<Itemset>) -> Vec<Itemset> {
    if itemsets.is_empty() {
        return vec![];
    }

    itemsets.sort_unstable();

    let mut final_itemsets: Vec<Itemset> = Vec::with_capacity(1024); // arbitrary
    let mut itemset_first_tuple: Itemset = Vec::with_capacity(itemsets[0].len() + 1);
    let mut tail_items: Vec<ItemId> = Vec::with_capacity(itemsets.len()); // based on analysis of the first for loop

    let mut i = 0;
    while i < itemsets.len() {
        let mut skip = 1;

        let (itemset_first, itemset_last) = itemsets[i].split_at(itemsets[i].len() - 1);
        let itemset_last = itemset_last.to_owned().pop().unwrap();

        tail_items.clear();
        tail_items.push(itemset_last);

        for j in (i + 1)..itemsets.len() {
            let (itemset_n_first, itemset_n_last) = itemsets[j].split_at(itemsets[j].len() - 1);
            let itemset_n_last = itemset_n_last.to_owned().pop().unwrap();

            if itemset_first == itemset_n_first {
                tail_items.push(itemset_n_last);
                skip += 1;
            } else {
                break;
            }
        }

        for combi in tail_items.iter().combinations(2).sorted() {
            itemset_first_tuple.clear();
            itemset_first_tuple.extend(itemset_first);
            let (a, b) = combi.split_at(1);
            let a = *a.to_owned().pop().unwrap();
            let b = *b.to_owned().pop().unwrap();

            itemset_first_tuple.push(a);
            itemset_first_tuple.push(b);
            // itemset_first_tuple.sort_unstable();
            final_itemsets.push(itemset_first_tuple.to_owned());
        }

        i += skip;
    }

    final_itemsets
}
/// Join k length itemsets into k + 1 length itemsets.
/// 
/// Algorithm translated from
/// https://github.com/tommyod/Efficient-Apriori/blob/master/efficient_apriori/itemsets.py
Join k length itemsets into k + 1 length itemsets.
Join k length itemsets into k + 1 length itemsets .
pub fn join_step(mut itemsets: Vec<Itemset>) -> Vec<Itemset> {
    if itemsets.is_empty() {
        return vec![];
    }
    itemsets.sort_unstable();
    let mut final_itemsets: Vec<Itemset> = Vec::with_capacity(1024); // arbitrary
    let mut itemset_first_tuple: Itemset = Vec::with_capacity(itemsets[0].len() + 1);
    let mut tail_items: Vec<ItemId> = Vec::with_capacity(itemsets.len()); // based on analysis of the first for loop
    let mut i = 0;
    while i < itemsets.len() {
        let mut skip = 1;
        let (itemset_first, itemset_last) = itemsets[i].split_at(itemsets[i].len() - 1);
        let itemset_last = itemset_last.to_owned().pop().unwrap();
        tail_items.clear();
        tail_items.push(itemset_last);
        for j in (i + 1)..itemsets.len() {
            let (itemset_n_first, itemset_n_last) = itemsets[j].split_at(itemsets[j].len() - 1);
            let itemset_n_last = itemset_n_last.to_owned().pop().unwrap();
            if itemset_first == itemset_n_first {
                tail_items.push(itemset_n_last);
                skip += 1;
            } else {
                break;
            }
        }
        for combi in tail_items.iter().combinations(2).sorted() {
            itemset_first_tuple.clear();
            itemset_first_tuple.extend(itemset_first);
            let (a, b) = combi.split_at(1);
            let a = *a.to_owned().pop().unwrap();
            let b = *b.to_owned().pop().unwrap();
            itemset_first_tuple.push(a);
            itemset_first_tuple.push(b);
            // itemset_first_tuple.sort_unstable();
            final_itemsets.push(itemset_first_tuple.to_owned());
        }
        i += skip;
    }
    final_itemsets
}
pub fn join_step ( mut itemsets : Vec < Itemset > ) -> Vec < Itemset > { if itemsets . is_empty ( ) { return vec ! [ ] ; } itemsets . sort_unstable ( ) ; let mut final_itemsets : Vec < Itemset > = Vec :: with_capacity ( 1024 ) ; // arbitrary let mut itemset_first_tuple : Itemset = Vec :: with_capacity ( itemsets [ 0 ] . len ( ) + 1 ) ; let mut tail_items : Vec < ItemId > = Vec :: with_capacity ( itemsets . len ( ) ) ; // based on analysis of the first for loop let mut i = 0 ; while i < itemsets . len ( ) { let mut skip = 1 ; let ( itemset_first , itemset_last ) = itemsets [ i ] . split_at ( itemsets [ i ] . len ( ) - 1 ) ; let itemset_last = itemset_last . to_owned ( ) . pop ( ) . unwrap ( ) ; tail_items . clear ( ) ; tail_items . push ( itemset_last ) ; for j in ( i + 1 ) .. itemsets . len ( ) { let ( itemset_n_first , itemset_n_last ) = itemsets [ j ] . split_at ( itemsets [ j ] . len ( ) - 1 ) ; let itemset_n_last = itemset_n_last . to_owned ( ) . pop ( ) . unwrap ( ) ; if itemset_first == itemset_n_first { tail_items . push ( itemset_n_last ) ; skip += 1 ; } else { break ; } } for combi in tail_items . iter ( ) . combinations ( 2 ) . sorted ( ) { itemset_first_tuple . clear ( ) ; itemset_first_tuple . extend ( itemset_first ) ; let ( a , b ) = combi . split_at ( 1 ) ; let a = * a . to_owned ( ) . pop ( ) . unwrap ( ) ; let b = * b . to_owned ( ) . pop ( ) . unwrap ( ) ; itemset_first_tuple . push ( a ) ; itemset_first_tuple . push ( b ) ; // itemset_first_tuple.sort_unstable(); final_itemsets . push ( itemset_first_tuple . to_owned ( ) ) ; } i += skip ; } final_itemsets }
Join k length itemsets into k + 1 length itemsets.
Join k length itemsets into k + 1 length itemsets .
itemsets
Vec<Itemset>
itemsets
Vec<Itemset>