我目前正在为我的投资组合构建一个电子商务商店应用,而我处于以下情况。
用户选择一个项目并将其添加到购物车,然后他们再次将同一项目添加到购物车。现在,当他们想要删除一项时,所有相同的项都将被删除。我当前正在使用过滤器方法,显然过滤器方法正在完成它的工作。
有人可以告诉我如何从购物车中删除一种产品,而不删除其所有类型吗?
谢谢您的时间。
这是我要过滤的数组的示例。
@Test
// Test Case # 1: User can login successfuly
//
public void Login() throws Exception {
// -- Setup
driver.get(constants.URL);
Assert.assertTrue("Error: Title is '" + driver.getTitle() + "', and should be company name Sign-on", driver.getTitle().startsWith("company name"));
// -- Test
driver.findElement(By.id("login")).sendKeys("username");
driver.findElement(By.id("password")).sendKeys("password");
driver.findElement(By.xpath("//*[@id=\"loginbox\"]/center[2]/input")).click();
Assert.assertTrue("Error: Title is '" + driver.getTitle() + "', and should be Country Name | TolaActivity", driver.getTitle().contains("asdasd"));
driver.quit();
}
}
答案 0 :(得分:1)
尝试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 :(得分:1)
您似乎正在尝试删除数组中某项的首次出现。 我建议您使用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);
答案 2 :(得分:0)
也许您可以找到数组中第一项的索引,并根据索引从数组中删除该项。一个例子:
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);
答案 3 :(得分:0)
您需要为购物车中的每个商品分配唯一的标识符。
例如,当您向卡中添加“ newItem”时:
newItem['uniqueItemId'] = {UniqueIdentifier};
selectedProducts.push(newItem);
这将使您可以访问对象上的uniqueItemId
,现在您可以按此值进行过滤,以便仅删除所需的项目:
selectedProducts = selectedProducts.filter(item => item.uniqueItemId !== {UniqueIdentifier});
答案 4 :(得分:0)
这里的答案略长,但是它显示了我们如何分配唯一的购物车ID,然后在删除时使用该ID进行过滤。
对于该演示,购物车ID只是一个Date.now()
,其值为Millisecs,因此对此应该是唯一的。
我们在添加到购物车期间分配唯一ID: 注意:我们会复制产品。
const addProductToCart = (id) => {
let product = Object.assign({}, products.find(p => p.id == id));
product.cartId = Date.now();**
cart.push(product);
renderCart();
};
现在,当您单击购物车中的某个物品(删除)时,我们将调用remove方法: 注意:我们使用购物车ID来引用商品,而不是产品ID
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]
});
};