Вычесть два массива с повторяющимися элементами

Допустим, у меня есть два массива следующим образом:

const A = ['Mo', 'Tu', 'We', 'Thu', 'Fr']
const B = ['Mo', 'Mo', 'Mo', 'Tu', 'Thu', 'Fr', 'Sa']

Я хочу вычесть массив A из массива B. Результат выглядит следующим образом:

const result = ['Mo', 'Mo', 'Sa']

Как этого добиться? Это кажется таким простым, но я не могу заставить его работать.

По сути, это должно удалить все из B, как только это будет в A.

Как упомянул @jarmod, ответ находится в этом посте, проверьте этот ответ: stackoverflow.com/a/36504668/7560262

Mauricio Cárdenas 17.11.2022 00:04

Выполнение разницы в наборе не будет содержать дубликатов в результате, поскольку набор не может иметь дубликатов по своей природе.

Tom el Safadi 17.11.2022 00:05
Поведение ключевого слова "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) для оценки ваших знаний,...
1
3
76
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Попробуй это:

const A = ['Mo', 'Tu', 'We', 'Thu', 'Fr']
const B = ['Mo', 'Mo', 'Mo', 'Tu', 'Thu', 'Fr', 'Sa']
let res = B;
A.forEach(val => {
  for(let i = 0; i < res.length; i++) {
    if (res[i] === val) {
      res.splice(res.indexOf(val), 1);
      break;
    }
  }
});

Это мутирует B. Замените let res = B; на const res = B.slice();.

Sebastian Simon 17.11.2022 00:35
Ответ принят как подходящий

const A = ['Mo', 'Tu', 'We', 'Thu', 'Fr']
const B = ['Mo', 'Mo', 'Mo', 'Tu', 'Thu', 'Fr', 'Sa']

console.info(A.reduce((b, a)=>
  (b.includes(a) && b.splice(b.indexOf(a),1), b), [...B]))

Без кода гольф:

const A = ['Mo', 'Tu', 'We', 'Thu', 'Fr']
const B = ['Mo', 'Mo', 'Mo', 'Tu', 'Thu', 'Fr', 'Sa']

console.info(A.reduce((b, a)=> {
  if (b.includes(a)) b.splice(b.indexOf(a), 1); return b; }, [...B]))

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

Tom el Safadi 17.11.2022 00:22

@TomelSafadi моя первая попытка изменила A на месте. Я только что обновил ответ, чтобы вернуть желаемый результат, сохранив при этом состояние A и B.

Andrew Parks 17.11.2022 00:24

Вы знаете, почему я получаю ошибку eslint для переменной b при любом изменении? Unexpected use of comma operator

Tom el Safadi 17.11.2022 00:56

@TomelSafadi Потому что ESLint не любит оператор запятой с включенным правилом no-sequences. Смотрите документацию. Вместо этого вы можете использовать A.reduce((b, a) => { if (b.includes(a)){ b.splice(b.indexOf(a), 1); } return b; }, B.slice()), чтобы не использовать этот синтаксис в стиле codegolf.

Sebastian Simon 17.11.2022 01:00

@TomelSafadi обычно это полезное предупреждение, которое может спасти вас, если вы неправильно поставили запятую и не хотели создавать выражение запятой. Однако мы намеревались использовать запятую. Если это вас беспокоит, вы можете удалить предупреждение, изменив его на это: console.info(A.reduce((b, a)=>b.includes(a) && b.splice(b.indexOf(a),1) && b || b, [...B]))

Andrew Parks 17.11.2022 01:00

const A = ['Mo', 'Tu', 'We', 'Thu', 'Fr']
const B = ['Mo', 'Mo', 'Mo', 'Tu', 'Thu', 'Fr', 'Sa']

const C = B.map(el => {
    const elIndexInA = A.findIndex(e => e === el)
    if (elIndexInA === -1) {
        return el
    }
    A.splice(elIndexInA, 1)
}).filter(el => el)

console.info(C)

Это мутирует A. Введите const res = A.slice(); и замените каждый A на res.

Sebastian Simon 17.11.2022 00:34

Это также не работает для A = [ undefined ]; B = [ undefined, undefined ];. Должно быть [ undefined ], но у вас получается []. Еще один неудачный тест: A = [ 1 ]; B = [ undefined, undefined ] (должно быть [ undefined, undefined ]).

Sebastian Simon 17.11.2022 00:57

@SebastianSimon хорошо, мой ответ связан с фрагментом кода в вопросе, вы можете настроить его для своих нужд, я почти уверен, что в большинстве случаев вы не вернете undefined как значение

Mohamed Oraby 17.11.2022 01:36

Забавный маленький filter() над картой А.

const A = ['Mo', 'Tu', 'We', 'Thu', 'Fr']
const B = ['Mo', 'Mo', 'Mo', 'Tu', 'Thu', 'Fr', 'Sa']

const aMap = A.reduce((a, c) => (a[c] = (a[c] ?? 0) + 1, a), {})
const result = B.filter(n => !(aMap[n]-- > 0))

console.info(result)

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