Ржавчина, как воссоздать функцию из 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.info(add([[1]], [[2]])); // [[3]]
console.info(add([1], [2])); // [3]

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

я хочу создать функцию, которая добавляет любое количество массивов любой глубины.

у меня есть 2 массива

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

как суммировать их с помощью этой функции в ржавчине, если myArray может иметь разную глубину в зависимости от ситуации

Ожидания: я ожидаю, что функция ржавчины будет работать

Stackoverflow - это не услуга «пожалуйста, напишите мне мой код», где вы говорите, что вам нужно, а затем уходите: покажите нам, что вы уже приложили все разумные усилия, чтобы сначала попробовать это самостоятельно. Без этого, согласно правилам публикации: найдите и исследуйте это, примените то, что найдете, и когда это не сработает после нескольких попыток, возможно, самое время обратиться за помощью в Stackoverflow.

Mike 'Pomax' Kamermans 04.06.2024 10:53
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
1
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В конце концов, ваша функция рекурсивно «складывает» значения вместе, при этом добавление массивов создает новый массив на основе поэлементного «добавления».

Итак, все, что нам нужно знать, это как «складывать» числа и как таким образом «складывать» массивы. Для общей обработки типов нам нужны черты; уже есть стандартная черта Add, так что давайте назовем нашу 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()
    }
}

И это действительно так, реализация Vec уже умеет рекурсивно обрабатывать себя (так что Vec<Vec<i32>> тоже работает автоматически).

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]]

ПРИМЕЧАНИЯ:

  • Было бы неплохо, если бы Combine автоматически работал из уже существующего Add (при условии, что это ваше намерение), но, к сожалению, это означает «конфликт» с Add для Vec - которого не существует, но компилятор не позволяет нам писать код если предположить, что это не так. Поэтому вам нужно будет определить Combine для всех типов, которые вы хотите «добавить» самостоятельно (макросы могут помочь, если вам нужно много).
  • Вы написали add(...args) так, что ему можно передать произвольное количество аргументов, но в Rust этого нет. Если вы этого хотите, вы можете создать макрос для итеративного построения .combine(...) или было бы лучше просто создать функцию, которая использует итератор значений для объединения - это легко .reduce.

спасибо, у меня работает. это то, что мне нужно. к сожалению, я не могу отказать вам в голосовании из-за низкой репутации из-за голосов против

Olgierd Kowalewski 04.06.2024 09:43

вы тот, кто задал вопрос, и вы всегда можете принять ответы на свои сообщения с вопросами, независимо от того, насколько низка ваша репутация.

Mike 'Pomax' Kamermans 04.06.2024 10:57

Другие вопросы по теме