Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Помогите с массивами в js (https://javascript.ru/forum/misc/78442-pomogite-s-massivami-v-js.html)

xcube 15.09.2019 20:10

Помогите с массивами в js
 
Всем привет!

Имеется 2 массива с объектами типа:

datas = [{name, price}] , [{name, price}];
datab = [{name, price2}] , [{name, price2}];

Извиняюсь за возможный кривой синтаксис - я новичок.
Нужно сравнить их, дедуплировать и соединить, что бы на выходе получилось:

dataz = [{name, price, price2}] , [{name, price, price2}]

name - совпадают, price - разные, но нужно их объединить.

Надеюсь попадаю под нужную категорию форума, но, за хороший ответ готов вознаградить.

рони 15.09.2019 20:29

xcube,
уточните структуру массивов!

xcube 15.09.2019 20:39

Наверное, я начудил, в консоли пишет так:

Array [ Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, ещё 39… ]

Если в лог вывести obj, то:

Object { name: "Кристал", price: "3" }

рони 15.09.2019 20:41

xcube,
const datas = [{name : 1, price : 100} , {name : 2, price : 45}],
      datab = [{name : 1, price2 : 5} , {name : 2, price2  : 33}],
      dataz = Array.from(datas, (v, i) => ({...v, ...datab[i]}));
console.log(dataz)

xcube 15.09.2019 21:23

рони,

Отдельно скрипт работает, а с моими массивами, почему то, нет(

Уточню: данный скрипт для imacros firefox.

const data = [];

var buy = window.document.querySelectorAll(".table-sell td[data-label='Вещь']");

for (var i = 0; i < buy.length; i++) {

var cName = buy[i].innerHTML.replace(/\s+/g, '');
var cPrice = buy[i].closest('tr').querySelector(".price").innerHTML.r eplace(/\s+/g, '');

var obj = {
name: cName, price: cPrice
}

data.push(obj);
}

window.console.log(data);

Так я заполнил массив data объектами. Может ошибся где?

рони 15.09.2019 21:35

Цитата:

Сообщение от xcube
а с моими массивами, почему то, нет(

скорее всего у вас иная структура второго массива, чем у первого.
сделайте массивы для примера.

xcube 15.09.2019 21:42

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

С вашими примерами массива всё работает.
Быть может я могу как то посмотреть структуру своих массивов?

рони 15.09.2019 21:45

Цитата:

Сообщение от xcube
Быть может я могу как то посмотреть структуру своих массивов?

Цитата:

Сообщение от xcube
window.console.log(data);

:-?
вы же смотрите.

рони 15.09.2019 21:47

xcube,
может нет price2 во втором массиве.
что мешает написать, что на входе двух массивов и что хотите получить?

xcube 15.09.2019 21:49

http://images.vfl.ru/ii/1568573337/0...c/27874800.png

Первые 2 массива - мои. Третий создался вашим решением.

рони 15.09.2019 21:49

Цитата:

Сообщение от xcube
Имеется 2 массива с объектами типа:

datas = [{name, price}] , [{name, price}];
datab = [{name, price2}] , [{name, price2}];

Извиняюсь за возможный кривой синтаксис - я новичок.
Нужно сравнить их, дедуплировать и соединить, что бы на выходе получилось:

dataz = [{name, price, price2}] , [{name, price, price2}]

name - совпадают, price - разные, но нужно их объединить.

нужны данные про ваши массивы datas, datab, и dataz

рони 15.09.2019 21:50

xcube,
диалог в стиле: испорченный телефон.

xcube 15.09.2019 21:54

рони,

const data = [];
const datas = [];


iimPlayCode('WAIT SECONDS=1');
iimPlayCode('SET !TIMEOUT 10\nTAG POS=1 TYPE=LABEL FORM=ACTION:?act=vendors ATTR=TXT:Продажа');
iimPlayCode('SET !TIMEOUT 10\nTAG POS=1 TYPE=BUTTON FORM=ACTION:?act=vendors ATTR=TXT:выбрать');
iimPlayCode('WAIT SECONDS=1');

var buy = window.document.querySelectorAll(".table-sell td[data-label='Вещь']");
//var linkList = window.document.querySelectorAll(".table-sell td[class='price']");

for (var i = 0; i < buy.length; i++) {

var cName = buy[i].innerHTML.replace(/\s+/g, '');
var cPrice = buy[i].closest('tr').querySelector(".price").innerHTML.r eplace(/\s+/g, '');

var obj = {
name: cName, price: cPrice
}

data.push(obj);
}

window.console.log(data);

iimPlayCode('WAIT SECONDS=1');
iimPlayCode('SET !TIMEOUT 10\nTAG POS=1 TYPE=LABEL FORM=ACTION:?act=vendors ATTR=TXT:Покупка');
iimPlayCode('SET !TIMEOUT 10\nTAG POS=1 TYPE=BUTTON FORM=ACTION:?act=vendors ATTR=TXT:выбрать');
iimPlayCode('WAIT SECONDS=1');


var sell = window.document.querySelectorAll(".table-sell td[data-label='Вещь']");

for (var i = 0; i < sell.length; i++) {

var cName = sell[i].innerHTML.replace(/\s+/g, '');
var cPrice = sell[i].closest('tr').querySelector(".price").innerHTML.r eplace(/\s+/g, '');

var obj2 = {
name: cName, price: cPrice
}

datas.push(obj2);

}


window.console.log(data);
window.console.log(datas);


const dataz = Array.from(data, (v, i) => ({...v, ...datas[i]}));


window.console.log(dataz)


В целом - моя идея - найти все продажи (массив data), найти все покупки (массив datas), сравнить цены и если покупают дороже цены продажи - оповещать меня.

рони 15.09.2019 21:57

xcube,
ок нет у вас price2 -- тогда что хотите получить в dataz ?

xcube 15.09.2019 22:11

рони,
for (var i = 0; i < sell.length; i++) {

var cName2 = sell[i].innerHTML.replace(/\s+/g, '');
var cPrice2 = sell[i].closest('tr').querySelector(".price").innerHTML.r eplace(/\s+/g, '');

var obj2 = {
name: cName2, price: cPrice2
}

datas.push(obj2);

}

Так поровней? Хотя не работает(

Получается у меня сейчас:

data = [{cName, cPrice}]...
datas = [{cName2, cPrice2}]...

рони 15.09.2019 22:15

xcube,
var obj2 = {
name: cName2, price2 сюда двойку: cPrice а не тут
}

var obj2 = {
name: cName2, price2: cPrice2
}

рони 15.09.2019 22:19

Цитата:

Сообщение от xcube
сравнить цены

для варианта без двоек !!!
const datas = [{name : 1, price : 100} , {name : 2, price : 45}],
      datab = [{name : 1, price : 5} , {name : 2, price  : 33}],
      dataz = Array.from(datas, (v, i) => (v.price -= datab[i].price, v));
console.log(dataz)
в price будет разница цен.

xcube 15.09.2019 22:26

рони,
Работает! Но коряво. Суть в том, что cName и cName2 в 99% случаев располагаются в разных ячейках массива.
Вообще таблица продаж состоит из 500+ объектов, а таблица покупок из 40+
Получается нужно cName сравнить с cName2, если сходство, то добавлять к объекту2 + cPrice, что бы получилось: {имя, цена покупки, цена продажи} в одном объекте и ячейке ?
Как это можно реализовать? Пожалуйста :help:

рони 15.09.2019 22:40

xcube,
const datas = [{name : 1, price : 100} , {name : 2, price : 45}, {name : 3, price : 400}],
      datab = [{name : 1, price : 5} , {name : 2, price  : 33}],
      dataz = datab.map((v,i) => {
      const {name} = v , ob = datas.find(({name : k}) => k == name);
      if (ob) v.цена = ob.price;
      return v
      })


console.log(dataz)

xcube 15.09.2019 23:04

рони,
Оо супер! Тесты то, что надо!
Но, когда запускаю со своим - виснет imacros с браузером
Это из-за 500 объектов в массиве? или старой версии лисы и imacros может быть?

рони 15.09.2019 23:21

xcube,
может так чуть быстрее будет.
const datas = [{name : 1, price : 100} , {name : 2, price : 45}, {name : 3, price : 400}],
      datab = [{name : 1, price : 5} , {name : 2, price  : 33}],
      obj = datas.reduce((obj, {name, price}) => (obj[name] = price, obj), {}),
      dataz = datab.map(v => {
      const {name} = v ;
      v.цена = obj[name] ;
      return v
      });


console.log(dataz)

xcube 15.09.2019 23:48

рони,
Ооо всё работает!
Остался последний шажок - если в dataz "price" больше "цены" - вывести клиенту инфу об объекте.
Решается перебором объектов в ячейках массива?
Помогите, пожалуйста.

рони 16.09.2019 00:00

xcube,
const datas = [{name : 1, price : 100} , {name : 2, price : 45}, {name : 3, price : 400}],
      datab = [{name : 1, price : 5} , {name : 2, price  : 330}],
      obj = datas.reduce((obj, {name, price}) => (obj[name] = price, obj), {}),
      arr = [],
      dataz = datab.map(v => {
      const {name} = v ;
      v.цена = obj[name];
      if (v.price > v.цена)  arr.push(v);
      return v
      });


console.log(arr, dataz)

xcube 16.09.2019 00:19

рони,
20 минут сижу думаю, не могу найти.
Где то что то не то, скрипт вывел 8 объектов (из 60 совпадений по cName) и у всех "price" меньше "цены"

рони 16.09.2019 00:40

xcube,
if (+v.price > +v.цена)  arr.push(v);
попробуйте так

xcube 16.09.2019 00:59

рони,
Работает! Всё отлично. Большое спасибо за помощь! :victory: :dance:

xcube 16.09.2019 02:13

Быть может есть способ ускорить и упростить? Один цикл 500+ объектов секунд 60 обрабатывает :-E
А после 2-3 циклов и вовсе перестает реагировать..

Alexandroppolus 16.09.2019 10:46

Цитата:

Сообщение от xcube
Один цикл 500+ объектов секунд 60 обрабатывает

мы, наверно, что-то не знаем? 500 объектов даже с предыдущим вариантом рони (где вложенный цикл) должны за полсекунды пролетать, не более

xcube 16.09.2019 22:58

Alexandroppolus,
Браузер зависает на секунд 10 именно в момент перебора.


Часовой пояс GMT +3, время: 22:53.