javascriptmathrustvectorporting

rust how recreate function from js


function add(...args){
  if (args.length === 0) return [];
  const a = args[0];
  let res = [];
  for (let i = 0; i < a.length; i++){
    const elements = args.map(x => x[i]);
    res.push(Array.isArray(a[i]) ? add(...elements) : elements.reduce((a, b) => a + b));
  }
  return res;
}
console.log(add([[1]], [[2]])); // [[3]]
console.log(add([1], [2])); // [3]

console.log(add([1, 2], [3, 4])); // [4, 6]
console.log(add([[1, 2]], [[3, 4]])); // [[4, 6]]

i want to create function which adds any amount of arrays with any depth.

i have 2 arrays

let myArray: Vec<...> = vec![...]; // and
let myArrayChanges: Vec<...> = vec![...];

how sum them with this function in rust if myArray can have diffrent depth depending on situation

Expectations: i expect working rust function


Solution

  • In the end, your function is recursively "adding" values together, where adding arrays creates a new array based on element-wise "adding".

    So all we need to know is how to "add" numbers and how to "add" arrays in such a fashion. For handling types generically we need traits; there is already a standard Add trait so lets call ours Combine:

    trait Combine {
        fn combine(self, other: Self) -> Self;
    }
    
    impl Combine for i32 {
        fn combine(self, other: i32) -> i32 {
            self + other
        }
    }
    
    impl<T> Combine for Vec<T> where T: Combine {
        fn combine(self, other: Vec<T>) -> Vec<T> {
            self.into_iter().zip(other).map(|(s, o)| s.combine(o)).collect()
        }
    }
    

    And that's really it, the Vec implementation already knows how to handle itself recursively (such that Vec<Vec<i32>> automatically works as well).

    fn add<T: Combine>(a: T, b: T) -> T {
        a.combine(b)
    }
    
    fn main() {
        let a = vec![1i32, 2, 3, 4];
        let b = vec![5i32, 6, 7, 8];
        
        println!("{:?}", add(a, b));
        
        let a = vec![vec![1i32, 2], vec![3, 4]];
        let b = vec![vec![5i32, 6], vec![7, 8]];
        
        println!("{:?}", add(a, b));
    }
    
    [6, 8, 10, 12]
    [[6, 8], [10, 12]]
    

    NOTES: