Day 13d: Advanced Vector Manipulation – Sorting, Searching, and Reversing

Venkat Annangi
Venkat Annangi
08/10/2024 02:21 3 min read 54 views
#rust-vectors #rust #108 days of rust

Day 13d: Advanced Vector Manipulation – Sorting, Searching, and Reversing

Introduction

Vectors in Rust offer a rich set of methods for data manipulation. Today, we will focus on advanced techniques for working with vectors, specifically sorting, searching, and reversing. These operations allow you to manage and manipulate large datasets efficiently, making vectors highly versatile.

Let’s explore each operation in detail, along with code examples.

Sorting Vectors

Rust provides two methods for sorting vectors: sort() for default sorting and sort_by() for custom sorting logic.

  • sort()
    The sort() method sorts the vector in place using Rust's default ordering, which typically follows lexicographical order for strings and numerical order for numbers.

    fn main() {
        let mut numbers = vec![3, 5, 1, 2, 4];
        numbers.sort();
        println!("{:?}", numbers);  // Output: [1, 2, 3, 4, 5]
    }
  • sort_by()
    If you need custom sorting logic, such as sorting in descending order or by specific fields in a struct, sort_by() allows you to pass a closure.

    fn main() {
        let mut numbers = vec![3, 5, 1, 2, 4];
        numbers.sort_by(|a, b| b.cmp(a));  // Sort in descending order
        println!("{:?}", numbers);  // Output: [5, 4, 3, 2, 1]
    }

Searching Vectors

Vectors provide several methods to search for elements. Some of the most useful are contains(), position(), and binary_search().

  • contains()
    The contains() method checks if a particular value exists in the vector. This method is simple but performs a linear search.

    fn main() {
        let numbers = vec![1, 2, 3, 4, 5];
        let has_three = numbers.contains(&3);
        println!("Contains 3: {}", has_three);  // Output: Contains 3: true
    }
  • iter().position()
    The position() method returns the index of the first occurrence of a value. If the value is not found, it returns None.

    fn main() {
        let numbers = vec![1, 2, 3, 4, 5];
        if let Some(pos) = numbers.iter().position(|&x| x == 3) {
            println!("Found 3 at position: {}", pos);  // Output: Found 3 at position: 2
        } else {
            println!("3 not found");
        }
    }
  • binary_search()
    If the vector is sorted, binary_search() can be used to find an element efficiently with a logarithmic time complexity. It returns a Result, where Ok contains the index of the element, and Err contains the index where the element could be inserted while maintaining order.

    fn main() {
        let numbers = vec![1, 2, 3, 4, 5];
        match numbers.binary_search(&3) {
            Ok(index) => println!("Found 3 at index: {}", index),  // Output: Found 3 at index: 2
            Err(_) => println!("3 not found"),
        }
    }

Reversing Vectors

Reversing a vector in Rust is straightforward using the reverse() method. This in-place operation reverses the order of elements without allocating new memory.

  • reverse()
     

    fn main() {
        let mut numbers = vec![1, 2, 3, 4, 5];
        numbers.reverse();
        println!("{:?}", numbers);  // Output: [5, 4, 3, 2, 1]
    }

Removing Duplicates

Another handy operation is removing adjacent duplicates from a sorted vector using the dedup() method. It eliminates consecutive duplicates but retains the first occurrence of the element.

  • dedup()
     

    fn main() {
        let mut numbers = vec![1, 2, 2, 3, 3, 3, 4, 5];
        numbers.dedup();
        println!("{:?}", numbers);  // Output: [1, 2, 3, 4, 5]
    }

Conclusion

By mastering sorting, searching, and reversing vectors, you gain powerful tools to handle complex data manipulation in Rust. These operations are highly optimized, making vectors the go-to choice for dynamic data structures.

Comments