Страницы

Поиск по вопросам

суббота, 30 ноября 2019 г.

Симметрическая разность

#javascript


Симметрическая разность wiki
Нужно найти симметрическую разность массивов.
Написал функцию сравнения двух массивов, в которой объединяю массивы в один и в цикле
ищу повторяющиеся значения. При нахождении удаляю.



function sym() {
  var args = Array.prototype.slice.call(arguments);
  var result = compareTwoArray(arguments[0], arguments[1]);
  
  if (arguments.length > 2) {
    
    for (var i = 2; i < arguments.length; i++) {
      // console.log('result = ' + result);
      result = compareTwoArray(result, arguments[i]);
    }
    
  }
  
  return result;
}

function compareTwoArray() {
  var args = Array.prototype.slice.call(arguments);
  var result = [];
  
  var newArr = args.reduce(function(prev, curr) {
    return prev.concat(curr);
  })
  
  for (var i = 0; i < newArr.length; i++) {
    
    var count = 0;
    
    for (var j = i+1; j < newArr.length; j++) {

      if (newArr[i] === newArr[j]) {
        count += 1;
        newArr.splice(j, 1);
        j -= 1;
      }
      
    }

    if (count === 0) {
      result.push(newArr[i]);
    }
    
  }

  return result;
}

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




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

[1, 2, 3]
[3, 1, 5]
[2, 5] - должен получиться
[2, 5] - получается с моим кодом


В другом оставить.

[1, 1, 3]
[4, 6]
[1, 3, 4, 6] - должен получиться
[3, 4, 6] - получается с моим кодом


В другом и оставить(1) и удалить(2).

[1, 1, 2, 5]
[2, 2, 3, 5]
[1, 3] - должен получиться
[3] - получается с моим кодом

    


Ответы

Ответ 1



Решение для двух массивов. Хотя 3 и больше массивов можно обрабатывать ступенчато: сначала два первых, потом результат первой обработки и 3 массив и так далее. function sum(arr1, arr2) { var tmp = arr1.concat(arr2), result = [], value, sum; for (var i = 0; i < tmp.length; i++) { var value = tmp[i]; if (result.indexOf(value) == -1) { sum = 0; if (arr1.indexOf(value) != -1) { sum++; } if (arr2.indexOf(value) != -1) { sum++; } if (sum == 1) { result.push(value); } } } return result; } console.log(sum([1, 2, 3], [3, 1, 5])); // [2, 5] console.log(sum([1, 1, 3], [4, 6])); // [1, 3, 4, 6] console.log(sum([1, 1, 2, 5], [2, 2, 3, 5])); // [1, 3]

Ответ 2



В яваскрипте есть класс Set, который в данном случае можно использовать в виде множества, в итоге запись получится почти по формуле В примере ниже использовался spread оператор, и rest-параметры function sym(...arrs) { return arrs.reduce((acc, arr, i) => { var accSet = new Set(acc), // множество из элементов первого массива arrSet = new Set(arr); // множество из элементов второго массива return [...accSet].filter(a => !arrSet.has(a)) // элементы первого множества без элементо второго .concat( // объединение [...arrSet].filter(a => !accSet.has(a)) // элементы второго множества без элементов первого ); }, []); } console.log(sym([1, 2, 3], [3, 1, 5])); // [2, 5] console.log(sym([1, 1, 3], [4, 6])); // [1, 3, 4, 6] console.log(sym([1, 1, 2, 5], [2, 2, 3, 5])); // [1, 3] console.log(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])); // [1, 4, 5] console.log(sym([1, 2, 5], [2, 3, 5], [3, 4, 5])); // [1, 4, 5]

Ответ 3



Как вариант еще можно сделать так: function sym() { var diff = []; // Допускаем, что симметричная разность пустого массива - пустой массив, // а симметричная разность одного массива - разность пустого массива // и этого массива равна самому этому массиву. // Также симметрическая разность равна объединению минус пересечение, // поэтому... [].forEach.call(arguments, function(arg) { var sum = diff.concat(arg); // ...объединяем массивы... diff = sum.filter(function(item) { // ...оставляем только те элементы, которые не найдены хотя бы // в одном из массивов... return (-1 === arg.indexOf(item) || -1 === diff.indexOf(item)); }); }); // ...возвращаем уникальные элементы // (иначе sym([1, 1, 2, 5], [2, 2, 3, 5]) будет [1, 1, 3]) return diff.filter(function(item, index, self) { return self.indexOf(item) === index; }); } console.log(sym()); console.log(sym([1, 2, 3])); console.log(sym([1, 2, 3], [3, 1, 5])); console.log(sym([1, 1, 3], [4, 6])); console.log(sym([1, 1, 2, 5], [2, 2, 3, 5])); console.log(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])); console.log(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]));

Ответ 4



Основывая на описании: Симметрическая разность двух множеств Вот пример для двух множеств (докрутить большее количество множеств, думаю, догадаетесь как): function getDiff(a, b){ let result = [], pointer = -1; if(!Array.isArray(a) || !Array.isArray(b)) throw new Error(`Both arguments must be arrays!`); a.forEach(e => { if((pointer = b.indexOf(e)) !== -1) b.splice(pointer, 1); else if(result.indexOf(e) === -1) result.push(e); }); b.forEach(e => { if((pointer = a.indexOf(e)) !== -1) a.splice(pointer, 1); else if(result.indexOf(e) === -1) result.push(e); }); return result; } // Пример с вики console.info(getDiff([1, 2, 3, 4, 5], [3, 4, 5, 6, 7])); // Ваши примеры console.info(getDiff([1, 2, 3], [3, 1, 5])); console.info(getDiff([1, 1, 3], [4, 6])); console.info(getDiff([1, 1, 2, 5], [2, 2, 3, 5]));

Комментариев нет:

Отправить комментарий