Форум программистов, компьютерный форум, киберфорум
Vue.js
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
 Аватар для diplodox
23 / 22 / 11
Регистрация: 07.10.2013
Сообщений: 90

Массив: Приложение по составлению списков товаров для дальнейшей работы с этим списком

24.07.2019, 11:10. Показов 1560. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем добрый день.

Недавно начал изучать Vue.js. Фреймворк очень понравился.
На данный момент создаю приложение по составлению списков товаров для дальнейшей работы с этим списком.

Данные по списку у меня хранятся в this.items, который вначале представляет из себя пустой массив.
Список создается динамически по за запросу штрихкода товара на API сервер, с этой частью я разобрался.
API по запросу возвращается json объекта товара. этот объект я пушу новым элементом в this.items.
Пример объекта товара:
JSON
1
2
3
4
5
6
7
8
9
10
11
{
article:2452695942,
brand:Zara,
description:ветровка,
img:http://192.168.11.100/images/items/_thumbs/2452695942.jpg,
barcode:02452695942109,
barcode_id:2592,
ean13:2452695942109,
size:sx,
q:1
}
Представляю список вот таким вот образом:

Если обратите внимание, на изображении вы можете увидеть, что строчки 1 и 2 идентичные.

Дело в том, что мне нужно представлять список как в таком виде, так и в схлопнутом виде.
В схлопнутом виде этот же список должен выглядетьт уже так:

То есть происходит "distinct" по ШК, при этом суммируется кол-во товара. Надеюсь вы поняли.

Для этого я создал поле this.isCollapsed, привязал к радио кнопке. В состоянии false должен отображаться шаблона как на первой картинке, при true, соответственно как на второй картинке.

Сначала для схлопнутого списка я создал новое поле this.itemsColapsed. И заполнял его параллельно с полем this.items при запросе. Но, пришел к мнению, что это не совсем правильно. Особенно учитывая, что есть интересный метов computed, который можно формировать при изменении this.items.

Вот тут то, соббсно, у меня и возникла проблемка, как формировать computed метод itemsCollapsed(). В методе он должен будет перебирать массив this.items, вытаскивать у него уникальные штрихкоды, на основе него формировать новый массив, а также нужно просуммировать все кол-ва каждого штрихкода.

Короче у меня получилось так:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
        computed: {
            itemsCollapsed: function(){
                //коллекция barcode_id, для последующей проверки
                let barcode_ids = new Set();
                //промежуточный массив, ключ и значение будут barcode_id и кол-во
                let arr = [];
                //результирующий массив, который мы вернем для itemsCollapsed
                let result = [];
                //перебираем все товары в this.items
                this.items.forEach((item_value) => {
                    //если в коллекции barcode_ids нет штрихкода
                    if (barcode_ids.has(item_value.barcode_id) === false) {
                        //вставляем товар в новый массив
                        result.push(item_value);
                        //добавляем в коллекцию barcode_id, чтобы с этим штрихкодом сюда не возвращаться
                        barcode_ids.add(item_value.barcode_id);
                        //доавбляем в промежуточный массив ключ ШК и значение - Кол-во
                        arr[item_value.barcode_id] = item_value.q;
                    } else {
                        //ежели в коллекции уже есть этот ШК, кто нужно просто добавить кол-во в промежуточный массив
                        arr[item_value.barcode_id] = parseInt(arr[item_value.barcode_id]) + parseInt(item_value.q);
                    }
                });
                //перебираем результирующий массив, для указания просуммированного кол-ва
                result.forEach((value, index) => {
                    result[index].q = arr[value.barcode_id];
                });
                return result;
            }
        },
Во первых работает не совсем корректно. Почему -то при каждоый итерации this.items.forEach, коллекция barcode_ids обнуляется. Не понял порчему...
И мой опыт подсказывает, что это можно сделать проще.
Есть ли варианты? Через reduce()? Может кто сталкивался с таким? Спасибо заранее за ответ.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.07.2019, 11:10
Ответы с готовыми решениями:

Как получить имя файла для дальнейшей работы с этим файлом?
Есть программа в которой используются функции GetOpenFile() и GetSaveFile() для открытия и сохранения файлов. Нужно получить из этих...

Считать числа из файла в массив для дальнейшей работы с ними
дан файл, в котором записаны данные: X 1 2 35 41 5 63 7 80 нужно считать ЧИСЛА из файла в массив для работы с ними. Никак не...

Как вернуть массив обьектов для дальнейшей работы с ним?
#include <iostream> class Ex { public: Ex(char *);//конструктор ~Ex();//деструктор (пока не используется) Ex...

7
431 / 302 / 90
Регистрация: 03.12.2015
Сообщений: 741
24.07.2019, 23:06
Отобрать уникальные элементы можно с помощью такого кода.
JavaScript
1
2
3
const unique = myArray.filter(
    (v, i, a) => a.findIndex(x => v.barcode_id === x.barcode_id) === i
);
Он оставляет первый из нескольких одинаковых элементов, остальные отбрасывает.
На больших списках будет тормозить, т.к. имеет сложность O(N^2).
1
 Аватар для diplodox
23 / 22 / 11
Регистрация: 07.10.2013
Сообщений: 90
25.07.2019, 09:45  [ТС]
Спасибо за ответ. Вставил ваше решение, но на выходе получается массив из уникальных значений. Как насчет просуммировать кол-во уникальных значений. Ну для решения моей задачи со списком в схлопнутом виде.
0
431 / 302 / 90
Регистрация: 03.12.2015
Сообщений: 741
25.07.2019, 11:06
Да, это чуть сложнее. В принципе, ты правильно все делал.

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* Подсчитывает количество одинаковых значений в массиве arr
   Элементы сравниваются по ключу key
   
   Возвращает массив объекто [{origin: ..., count: ...}], в котором:
   origin - исходный элемент массива arr с уникальным key
   count - количество вхождений такого элемента
*/
function countByKey(arr, key) {
  const result = {};
  arr.forEach(elem => {
    const id = elem[key];
    if (!result[id]) 
        result[id] = {origin: elem, count: 0};
    result[id].count++;
  });
  return Object.values(result);
}
Пример:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var arr = [
  {barcode_id:1, detail:'A'},
  {barcode_id:1, detail:'A'},
  {barcode_id:2, detail:'B'},
  {barcode_id:2, detail:'B'},
  {barcode_id:1, detail:'A'},
  {barcode_id:3, detail:'C'}
]
 
var counts = countByKey(arr, 'barcode_id');
 
// Вывод counts
 
[
  {"origin":{"barcode_id":1,"detail":"A"},"count":3},
  {"origin":{"barcode_id":2,"detail":"B"},"count":2},
  {"origin":{"barcode_id":3,"detail":"C"},"count":1}
]
0
 Аватар для diplodox
23 / 22 / 11
Регистрация: 07.10.2013
Сообщений: 90
25.07.2019, 12:41  [ТС]
Нашел решение:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
computed: {
            itemsCollapsed: function () {
                const data = this.items;
                const result = Object.values(
                    data.reduce(
                        (acc, cur) => (
                            (
                                !acc[cur.barcode_id]
                                    ? (acc[cur.barcode_id] = cur)
                                    : acc[cur.barcode_id].q += cur.q
                            ), acc), {}));
                return result;
            }
        },

Правда снова столкнулся с непонятной для меня проблемой.
Почему то этот метод влияет на сами данные this.items.

Можно видеть на картинках ниже, я пошагово добавляю по одному и тому же товару в this.data.
В секции Not collapsed отображается не схлопнутые, в Colalpsed - схлопнутые

Шаг 1, добавляем первый товар:

Здесь все ок пока.

Шаг 2, добавляю тот же товар еще раз:

По идее должен был добавиться товар с кол-вом - 1, но почему то кол-во указано - 2, а в схлопнутом посчитано верно.

Ну и Шаг 3, добавлю еще раз такой же товар:

Как то так, кол-ва совсем неверные у несхлопнутого и схлопнутого.


Дело в computed функции? Каким образом в нем изменяется this.data? Помогите плз!
0
431 / 302 / 90
Регистрация: 03.12.2015
Сообщений: 741
25.07.2019, 13:08
Цитата Сообщение от diplodox Посмотреть сообщение
Правда снова столкнулся с непонятной для меня проблемой.
Почему то этот метод влияет на сами данные this.items.
JavaScript
1
2
3
!acc[cur.barcode_id]
  ? (acc[cur.barcode_id] = cur)   // (1)
  : acc[cur.barcode_id].q += cur.q   // (2)
Ты проходишь по элементам this.items. Некоторые элементы ты записываешь в acc (1). Позже ты этот элемент меняешь в (2). В acc хранится не копия элемента, а ссылка на него. Поэтому при изменении элемента acc меняется соответствующий элемент в items.

Возможные решения: либо делать копию элемента при записи его acc (в (1)), либо не менять их (в (2)), т.е. хранить количество отдельно от элемента (как в моем коде выше).
1
 Аватар для diplodox
23 / 22 / 11
Регистрация: 07.10.2013
Сообщений: 90
25.07.2019, 13:39  [ТС]
Дельный совет. А еще можно клонировать объект изначально и работать с клоном.
Думаю так и сделаю.
Кстати, загуглил, как в Vue.js можно клонировать объекты...
Вобщем я был в недоумении что предлагают на официальном форуме:

If you have an object that is already reactive, you can clone a fresh copy using JSON.parse(JSON.stringify(obj))
Костыльно как то.

Так или иначе, спасибо большое за помощь. Тему можно закрыть.
0
431 / 302 / 90
Регистрация: 03.12.2015
Сообщений: 741
25.07.2019, 14:10
Цитата Сообщение от diplodox Посмотреть сообщение
Костыльно как то.
Javascript не умеют делать deepcopy "из коробки" (как и многие другие языки). Самый простой способ сделать полную копию объекта - использовать json. Это вопрос не к Vue, а к js.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.07.2019, 14:10
Помогаю со студенческими работами здесь

Есть массив в виде табличных данных, как его поделить на отдельные элементы для дальнейшей работы?
Есть массив в виде табличных данных,как его поделить на отдельные элементы для работы дальше?строка разделена ";",нужен кусочек...

Разработать программу работы со списком очередей списков
Разработайте программу работы со списком очередей списков. Программа должна содержать следующие процедуры, вызываемые из меню: ...

Объявить класс, содержащий массив, индексатор для работы с этим массивом и приватный конструктор
Объявить класс, содержащий одномерный целочисленный массив, индексатор для работы с этим массивом, а также приватный конструктор,...

Объявить класс, содержащий одномерный целочисленный массив размерностью 10, индексатор для работы с этим массивом
Объявить класс, содержащий одномерный целочисленный массив размерностью 10, индексатор для работы с этим массивом, а также конструктор по...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru