Skip to main content

attribute_count

Function attribute_count 

Source
pub fn attribute_count<T, K: PartialEq>(
    elements: impl IntoIterator<Item = T>,
    attribute: impl Fn(T) -> Option<K>,
) -> Vec<(K, usize)>
Expand description

How often each value of some property of a stream’s elements comes, in the order each value is first met: music21’s attributeCount, with the property a function of the element rather than the name of one, and None where the element has no such property – which is music21’s hasattr test.

The elements are whatever reading the caller counts over: a stream’s own events, a recursive one (recurse, leaves), or either of those filtered, as music21 takes a stream or a stream iterator.

The counts are in counting order, as Python’s Counter keeps them, so most_common is a sort by count that leaves ties as they stand.

use music21_rs::analysis::elements::attribute_count;
use music21_rs::stream::StreamElement;
use music21_rs::tinynotation::from_tiny_notation;

let line = from_tiny_notation("4/4 c4 d8 e8 f2")?;
let lengths = attribute_count(line.recurse(), |(_, element)| match element {
    StreamElement::Note(_) => Some(element.quarter_length()),
    // A clef or a meter is not a note, and is not counted -- as
    // music21 passes over an element the attribute is not on.
    _ => None,
});
assert_eq!(lengths, [(1.0, 1), (0.5, 2), (2.0, 1)]);