Как сопоставить элементы объекта, которые уникальны и не повторяются

Я создаю собственное приложение для электронной коммерции, и в разделе приложения «КОРЗИНА» я хочу, чтобы каждый элемент, добавленный в корзину с тем же идентификатором (идентификатор категории, который вы видите в консоли), отображался только один раз, но в моем случае если я добавлю в корзину 3 товара с одинаковым идентификатором, я увижу 3 разных списка их уважаемых товаров. Я хочу, чтобы моя функция карты отображала 1 элемент списка, если есть несколько элементов с одинаковым идентификатором с добавленным количеством. Мой код пока просто отображает каждый выбранный продукт как отдельный элемент:

renderItems() {
let items = [];
this.state.cartItems.map((item, i) => {
  console.log(item)
  items.push(
    <ListItem
      key={i}
      last={this.state.cartItems.length === i + 1}
      onPress={() => this.itemClicked(item)}
    >
      <Thumbnail square style={{ width: 100, height: 100 }} source={{ uri: item.productdetail.image }} />
      <Body style={{ paddingLeft: 10 }}>
        <Text style={{ fontSize: 16 }}>

          {item.productdetail.name}

        </Text>

        <Text style={{ fontSize: 14, fontStyle: 'italic' }}>Price: {item.productdetail.price}</Text>
        <Text style={{ fontSize: 14, fontStyle: 'italic' }}>Quantity: {item.quantity > 1 ? item.quantity : 1}</Text>

      </Body>
      <Right>
        <Button style={{ marginLeft: -25 }} transparent onPress={() => this.removeItemPressed(item)}>
          <Icon size={30} style={{ fontSize: 30, color: '#95a5a6' }} name='ios-remove-circle-outline' />
        </Button>
      </Right>
    </ListItem>
  );
});
return items;}

Результат console.log выглядит следующим образом:  введите описание изображения здесь

Так выглядит моя корзина  введите описание изображения здесь

Теперь, как вы можете видеть, в корзине должен отображаться только один список, у элемента с таким же товаром количество = 18.


person abbu jan    schedule 10.08.2018    source источник
comment
фильтровать данные на основе id, затем перебирать содержимое с помощью map   -  person CodeZombie    schedule 10.08.2018


Ответы (2)


Учитывая, что у вас есть такой простой набор данных:

const rawItemsData = [
    {id: 1, qty: 2},
    {id: 1, qty: 3},
    {id: 2, qty: 1},
    {id: 1, qty: 2},
    {id: 2, qty: 5},
    {id: 3, qty: 6}
];

Если вы хотите получить массив с уникальными идентификаторами элементов и суммированным количеством, вы можете использовать reduce:

const uniqueItemsData = rawItemsData.reduce((prev, item) => {
    const existingItem = prev.find(({id}) => id === item.id);
    if(existingItem)
        existingItem.qty = existingItem.qty + item.qty;
    else
        prev.push(item);
   return prev;
 }, []); //-> [ { id: 1, qty: 7 }, { id: 2, qty: 6 }, { id: 3, qty: 6 } ];


 //Then you can use your code : 
 uniqueItemsData.map((item, id) => {
     //..
 });
person Logar    schedule 10.08.2018
comment
В prev.find (({id}) = ›id === item.id); что я получу в 'id'? - person abbu jan; 10.08.2018
comment
В этой строке используется деструктуризация объекта. find будет перебирать существующие элементы и выполнять обратный вызов. В этом обратном вызове переменная id будет содержать значение свойства текущего элемента id - person Logar; 10.08.2018
comment
проще говоря, вы также можете написать: prev.find((testItem) => testItem.id === item.id); - person Logar; 10.08.2018
comment
Вы отредактировали мой ответ, что сделало его менее читабельным, поэтому я отклонил редактирование. Но да, я думаю, ты был прав - person Logar; 10.08.2018
comment
У меня ошибка типа: '' undefined не является объектом (testItem.productDetail) - person abbu jan; 10.08.2018
comment
Можете ли вы предложить мне эту линию по моим данным? - person abbu jan; 10.08.2018
comment
Позвольте нам продолжить это обсуждение в чате. - person Logar; 10.08.2018

В этом случае вы должны сделать простой контроль перед нажатием, независимо от того, существует ли элемент или нет. Вам решать, как это сделать:

Например, вы можете создать другой список, содержащий уникальные элементы. Я считаю, что на такой странице полезно хранить уникальные предметы, вам может понадобиться соответствующая информация где-то еще. И этот список не должен требовать setState, потому что он предназначен только для управления.

this.state.uniqueItems = [];

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

this.state.uniqueItems.push(item);

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

person Faruk Yazici    schedule 10.08.2018