Предотвратите повторяющиеся продукты, которые будут удалены из корзины - PullRequest
0 голосов
/ 27 марта 2019

В настоящее время я создаю приложение интернет-магазина для своего портфолио, и я нахожусь в следующей ситуации.

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

Может кто-нибудь сказать мне, как я могу удалить один продукт из моей корзины, не удаляя все его типы?

Спасибо за ваше время.

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

selectedProducts = [
{
  id: 12,
  sku: 12064273040195392,
  title: "Cat Tee Black T-Shirt",
  availableSizes: ["XS", "S"],
  style: "Black with custom print",
  price: 10.9,
  imgUrl: photo1,
  currencyId: "GBP",
  currencyFormat: "£",
  isFreeShipping: true
},
{
  id: 13,
  sku: 51498472915966370,
  title: "Dark Thug Blue-Navy T-Shirt",
  availableSizes: ["M"],
  style: "Front print and paisley print",
  price: 29.45,
  imgUrl: photo2,
  currencyId: "GBP",
  currencyFormat: "£",
  isFreeShipping: true
},
{
  id: 12,
  sku: 12064273040195392,
  title: "Cat Tee Black T-Shirt",
  availableSizes: ["XS", "S"],
  style: "Black with custom print",
  price: 10.9,
  imgUrl: photo1,
  currencyId: "GBP",
  currencyFormat: "£",
  isFreeShipping: true
} ];

Ответы [ 5 ]

1 голос
/ 27 марта 2019

Вы можете использовать Array.prototype.reduce при попытке filter из нескольких предметов.

Это вернет объект с массивом для каждого выбранного элемента.Длина массивов будет равна количеству элементов каждого id.

let items = selectedProducts.reduce((a,v) => {
  a[v.id] ?  a[v.id].push(v) : a[v.id] = [v];
  return a;
}, {});

более компактная версия:

selectedProducts.reduce((a,v)=>(a[v.id]?a[v.id].push(v):a[v.id]=[v],a),{});

let selectedProducts = [
{
  id: 12,
  sku: 12064273040195392,
  title: "Cat Tee Black T-Shirt",
  availableSizes: ["XS", "S"],
  style: "Black with custom print",
  price: 10.9,
  imgUrl: 'photo1',
  currencyId: "GBP",
  currencyFormat: "£",
  isFreeShipping: true
},
{
  id: 13,
  sku: 51498472915966370,
  title: "Dark Thug Blue-Navy T-Shirt",
  availableSizes: ["M"],
  style: "Front print and paisley print",
  price: 29.45,
  imgUrl: 'photo2',
  currencyId: "GBP",
  currencyFormat: "£",
  isFreeShipping: true
},
{
  id: 12,
  sku: 12064273040195392,
  title: "Cat Tee Black T-Shirt",
  availableSizes: ["XS", "S"],
  style: "Black with custom print",
  price: 10.9,
  imgUrl: 'photo1',
  currencyId: "GBP",
  currencyFormat: "£",
  isFreeShipping: true
} ];

let items = selectedProducts.reduce((a,v) => {
a[v.id] ?  a[v.id].push(v) : a[v.id] = [v];
return a;
}, {});

console.log(items);
1 голос
/ 27 марта 2019

Похоже, вы пытаетесь удалить первое вхождение элемента в массиве, который у вас есть. Я бы посоветовал вам попробовать что-то подобное, используя методы indexOf и splice.

function removeFromCart ( sku ) {
  const index = selectedProducts.indexOf( sku );
  selectedProducts.splice( index, 1 ); 
}

Предпочтительно использовать splice и indexOf вместе, так как javascript сделает удаление на месте за вас без необходимости создавать аккумулятор (когда вы используете Reduce). код также проще и легче для чтения.

Сложность времени - O (n) Космическая сложность - O (1)

Вы можете использовать редуктор для решения проблемы, но вам придется создать объект для хранения результатов, увеличивая сложность пространства до O (n)

let selectedProducts = [
    {
      id: 12,
      sku: 12064273040195392,
      title: "Cat Tee Black T-Shirt",
      availableSizes: ["XS", "S"],
      style: "Black with custom print",
      price: 10.9,
      imgUrl: 'photo1',
      currencyId: "GBP",
      currencyFormat: "£",
      isFreeShipping: true
    },
    {
      id: 13,
      sku: 51498472915966370,
      title: "Dark Thug Blue-Navy T-Shirt",
      availableSizes: ["M"],
      style: "Front print and paisley print",
      price: 29.45,
      imgUrl: 'photo2',
      currencyId: "GBP",
      currencyFormat: "£",
      isFreeShipping: true
    },
    {
      id: 12,
      sku: 12064273040195392,
      title: "Cat Tee Black T-Shirt",
      availableSizes: ["XS", "S"],
      style: "Black with custom print",
      price: 10.9,
      imgUrl: 'photo1',
      currencyId: "GBP",
      currencyFormat: "£",
      isFreeShipping: true
    } ];

    const index = selectedProducts.indexOf( 12064273040195392 );
    selectedProducts.splice( index, 1 );

    console.log(selectedProducts);
0 голосов
/ 27 марта 2019

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

Для демонстрации идентификатор корзины - это просто Date.now(), значение которого равно миллисекундам, поэтому должно быть уникальным для этого.

Мы присваиваем уникальный идентификатор при добавлении в корзину: ПРИМЕЧАНИЕ: мы копируем продукт.

const addProductToCart = (id) => {
  let product = Object.assign({}, products.find(p => p.id == id));
  product.cartId = Date.now();**
  cart.push(product);
  renderCart();
};

Теперь, когда вы щелкаете по элементу в корзине (удаляете), мы вызываем метод удаления: ПРИМЕЧАНИЕ. Мы используем идентификатор корзины для ссылки на товар, а НЕ идентификатор продукта

const removeFromCart = (cartId) => {
  cart = cart.filter(item => item.cartId != cartId);
  renderCart();
};

Ниже приведен рабочий фрагмент, показывающий принципы работы.

let products = [
  {
    id: 1,
    name: "product one"
  },
  {
    id: 2,
    name: "product two"
  },
  {
    id: 3,
    name: "product three"
  }
];

let cart = [];

const renderProduct = (product) => `<li class="product" data-id="${product.id}">${product.name}</li>`;

const renderCartItem = (cartItem) => `<li class="cartItem" data-cart-id="${cartItem.cartId}">${cartItem.name}</li>`;

const renderCart = () => {
  document.querySelector('.cart').innerHTML = cart.map(c => renderCartItem(c)).join('');
};

const addProductToCart = (id) => {
  let product = Object.assign({}, products.find(p => p.id == id));
  product.cartId = Date.now();
  cart.push(product);
  renderCart();
};

const removeFromCart = (cartId) => {
  cart = cart.filter(item => item.cartId != cartId);
  renderCart();
}

document.addEventListener('DOMContentLoaded', () => {
  document.querySelector('.items').innerHTML = products.map(p => renderProduct(p)).join('');
});

document.addEventListener('click', (e) => {
  if(e.target.matches('.product')) {
    addProductToCart(e.target.dataset.id);
  }

  if(e.target.matches('.cartItem')) {
    removeFromCart(e.target.dataset.cartId);
  }

});
<ul class="items"></ul>
    <ul class="cart"></ul>

Некоторые примечания относительно ссылки на объект и почему мы должны копировать наш объект при переходе от списка товаров к списку корзин.

В этом первом фрагменте мы добавляем без какой-либо копии объекта. ПРИМЕЧАНИЕ: даже если мы добавим свойство к cart[0], оно фактически добавится ко всем. Потому что это reference, а на самом деле массив всего лишь pointers для того же объекта.

let products = [
  { 
    id: 1,
    name: "one"
  },
  { 
    id: 1,
    name: "one"
  }  
];

let cart = [];

// Add without copy
for(let i=0; i< 3; i++) {
  cart.push(products[0]);
}

// now add an attribute to one cart item
cart[0].cartId = 1;

cart.forEach(item => console.log(item));

поэтому нам нужно скопировать наш объект, используя Object.assign. Это создает новые экземпляры, и поэтому каждый pointer указывает на различный object

let products = [
  { 
    id: 1,
    name: "one"
  },
  { 
    id: 1,
    name: "one"
  }  
];

let cart = [];

// Add without copy
for(let i=0; i< 3; i++) {
  cart.push(Object.assign({}, products[0]));
}

// now add an attribute to one cart item
cart[0].cartId = 1;

cart.forEach(item => console.log(item));

Измените добавление в корзину на это:

addCartItems = data => {
  copyData = Object.assign({}, data);
  copyData.cartId = Date.now();
  this.setState({
    cartItems: [...this.state.cartItems, copyData]
  });
};
0 голосов
/ 27 марта 2019

Вам нужен уникальный идентификатор для каждого элемента в корзине.

Например, когда вы добавляете 'newItem' на карту:

newItem['uniqueItemId'] = {UniqueIdentifier};
selectedProducts.push(newItem);

Это даст вам доступ к uniqueItemId на объекте, и теперь вы можете фильтровать по этому значению, чтобы удалить только нужный элемент:

selectedProducts = selectedProducts.filter(item => item.uniqueItemId !== {UniqueIdentifier});
0 голосов
/ 27 марта 2019

Может быть, вы можете найти индекс первого элемента в массиве и удалить элемент из массива на основе индекса.Пример:

var selectedProducts = [
{
  id: 12,
  sku: 12064273040195392,
  title: "Cat Tee Black T-Shirt",
  availableSizes: ["XS", "S"],
  style: "Black with custom print",
  price: 10.9,
  imgUrl: 'photo1',
  currencyId: "GBP",
  currencyFormat: "£",
  isFreeShipping: true
},
{
  id: 13,
  sku: 51498472915966370,
  title: "Dark Thug Blue-Navy T-Shirt",
  availableSizes: ["M"],
  style: "Front print and paisley print",
  price: 29.45,
  imgUrl: 'photo2',
  currencyId: "GBP",
  currencyFormat: "£",
  isFreeShipping: true
},
{
  id: 12,
  sku: 12064273040195392,
  title: "Cat Tee Black T-Shirt",
  availableSizes: ["XS", "S"],
  style: "Black with custom print",
  price: 10.9,
  imgUrl: 'photo1',
  currencyId: "GBP",
  currencyFormat: "£",
  isFreeShipping: true
} ];


const index = selectedProducts.findIndex(obj => obj.id == 12);
selectedProducts.splice(index, 1);
console.log(selectedProducts);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...