• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Porównywanie w pętli elementów 2 tablic o różnej długości

Object Storage Arubacloud
0 głosów
642 wizyt
pytanie zadane 17 grudnia 2015 w JavaScript przez ScriptyChris Mędrzec (190,190 p.)

Pytanie pewnie banalne, ale coś mi nie idzie.

Mam tablicę 7 elementów

var headers = ['id', 'producent', 'model', 'ekran', 'procesor', 'ram', 'cena'];

Wczytuję sobie plik XML, który składa się z tagów <product>, w których siedzą tagi z tablicy headers (a w nich siedzą odpowiednie własności, jak <producent>Sony</producent>  itd).

Wczytany plik XML "melduje się" jako string, który rozbijam metodą split('\n'); na poszczególne linijki i umieszczam w tablicy arr. Czyli w tej nowej tablicy mam (jako oddzielne elementy) po prostu kolejne linijki z pliku XML.

Chciałem w pętli (iterując po długości tablicy arr, w której jest cały plik XML rozbity na linijki) porównywać, czy w danej linijce w tagach <> znajduje się to samo, co w danym elemencie tablicy headers. Główny problem polega na tym, że tablica headers jest krótsza od arr. Udało mi się wypisać elementy headers w pętli iterującej po arr, ale gdy skończy się 1 produkt, to pętla leci dalej i pokazuje kolejne linijki pliku XML - ale elementy headers "gubią" iteracje, przez co są źle pokazywane (a nawet w 1 produkcie zamiast "cena" jest już "id").

Kod pętli:

for (var i=0,j=i-2; i< arr.length; i++)
 {
	console.log(arr[i],'  ',global.headers[j]);
	j++;				
	if (j == 6) 
	{
		j=0;
	}
}

To pokazuje konsola:

 

Jak więc mogę porównać elementy 2 tablic o różnej długości?

3 odpowiedzi

+1 głos
odpowiedź 17 grudnia 2015 przez makoso Mądrala (7,380 p.)
wybrane 17 grudnia 2015 przez ScriptyChris
 
Najlepsza
Jeżeli chodzi Ci poprostu o odebranie danych z XML-a to chyba tutaj masz idealny przykład:

http://kursjs.pl/kurs/jquery/jquery_ajax.html#xml
komentarz 17 grudnia 2015 przez makoso Mądrala (7,380 p.)
i tablica wielowymiarowa zapisujesz produkt i mu dopisujesz tablicę z danymi z kluczami "cena" itd
komentarz 17 grudnia 2015 przez ScriptyChris Mędrzec (190,190 p.)

W JavaScript do tego będą, któraś z metod splice/slice?

komentarz 17 grudnia 2015 przez makoso Mądrala (7,380 p.)
do wybierania pola <cena>22</cena> możesz zrobić tak:
1. "<cena>22</cena>".replace(headers[x], "");

2.usuwasz końcówkę </cena> w następujący sposób
-bierzesz wymiar tablicy "22</cena>" zapisujesz do var nowLength :)
-wyciągasz cenę  "22</cena>".substring(0, nowLength - (headers[x].length + 1))

masz już tylko cenę powinieneś sobie poradzić brzydko opisałem ale myślę że załapiesz nie mam już czasu tego zapisać po ludzku :)
komentarz 17 grudnia 2015 przez ScriptyChris Mędrzec (190,190 p.)

Uff, trochę zeszło, ale się udało 

var shortenH = [];			  
      shortenH=global.headers;			  

 shortenH.shift();
var headersL = shortenH.length;

  var iC = 1, arrEL=0;
for (var i=0, j=0; i<iterator.length;i++)
 {
	arr[iterator[i]] = arr[iterator[i]].replace(/ /g,'');						  
	arr[iterator[i]] = arr[iterator[i]].replace(shortenH[j], "");					
	arr[iterator[i]] = arr[iterator[i]].slice(2,arr[iterator[i]].length);
	arr[iterator[i]] = arr[iterator[i]].slice(0, -(shortenH[j].length+3));
					
	console.log(arr[iterator[i]]); 
	j++;
	if (i == (headersL*iC)-1)
	 {
		  j=0;
		  iC++;
	 }			  
}

Konsola

Wielkie dzięki za znalezienie takiej metody. Może i na około, ale za to slice poćwiczone :)

komentarz 17 grudnia 2015 przez makoso Mądrala (7,380 p.)
No i ja mini js-a poćwiczyłem :)
Normalnie nic w nim nie staram się pisać :)
+1 głos
odpowiedź 17 grudnia 2015 przez Comandeer Guru (601,110 p.)

Jak parsujesz XML jako string to znaczy, że robisz to źle. XML traktuje się jako DOM i przepuszcza przez ten sam parser, co HTML. Wówczas uzyskujemy normalną drzewiastą strukturę, po której możemy chodzić. I to de facto rozwiązuje nam większość problemów.

var dom = (new DOMParser()).parseFromString(`<?xml version="1.0" encoding="utf-8"?>
<products>
  <product>
    <producent>Apple</producent>
    <model>iPhone 4s</model>
    <ekran>3.5"</ekran>
    <procesor>2x800MHz</procesor>
    <ram>512MB</ram>
    <cena>490</cena>
  </product>
  <product>
    <producent>Motorola</producent>
    <model>G3</model>
    <ekran>5"</ekran>
    <procesor>4x1.4GHz</procesor>
    <ram>1GB</ram>
    <cena>780</cena>
  </product>
  <product>
    <producent>SONY</producent>
    <model>Xperia X10</model>
    <ekran>4"</ekran>
    <procesor>1GHz</procesor>
    <ram>384MB</ram>
    <cena>80</cena>
  </product></products>`, 'text/xml');

Zmienna dom ma te same metody do przeczesywania drzewka, co struktura samej strony, więc bez problemu można się bawić choćby przez dom.querySelector.

komentarz 17 grudnia 2015 przez ScriptyChris Mędrzec (190,190 p.)

Tylko, że ja wczytuje plik XML jako tekst. Więc nie wiem, czy mogę z tego korzystać tak jak to przedstawiłeś (jako obiekt DOM).

loadFromXML: function()
 {
	 var xmlInput = document.getElementById('readFromXML');
	xmlInput.addEventListener('change', function(e) {	 
				
          var sesData = global.produkty.mysql;
          var result = [];//data = [],
		  
          var file = xmlInput.files[0];
	  var reader  = new FileReader(),
	    file    = event.currentTarget.files[0];
	  reader.onload = function(data) {
	 var data = this.result;
	//console.log(data);
	var arr = [];
	arr = (data.split('\n'));
	console.log('ARR ',arr);
}

 

komentarz 17 grudnia 2015 przez Comandeer Guru (601,110 p.)
Przecież w moim przykładzie DOM jest tworzony ze stringu, więc nie wiem w czym problem?
komentarz 17 grudnia 2015 przez ScriptyChris Mędrzec (190,190 p.)

Coś nie chce się wczytać. Podstawiłem zamiast stringa, zmienną data, bo do niej jest u mnie wstawiany tekst otrzymany z wczytanego pliku XML. I pojawia mnie się taki "błąd" http://imgur.com/wQI8W41

komentarz 17 grudnia 2015 przez Comandeer Guru (601,110 p.)

A zobacz co jest w zmiennej data

komentarz 17 grudnia 2015 przez ScriptyChris Mędrzec (190,190 p.)
Wklejone z konsoli http://wklej.org/id/1880661/ Chyba brakuje na końcu kilku tagów i na początku jakieś 3 dziwne znaki się pojawiły. A gdy ten sam plik otworzę w notatniku to jest ok.
komentarz 17 grudnia 2015 przez Comandeer Guru (601,110 p.)

Tak, brakuje zamknięcia products. A te znaczki na początku to BOM (a notatnik jest tak głupi, że tego nie widzi).

komentarz 17 grudnia 2015 przez ScriptyChris Mędrzec (190,190 p.)

Czyli zanim umieszczę zmienną data w DOMParser, to jakimś slice'm usunąć te znaczniki i dopisać na koniec stringa "products"?

komentarz 17 grudnia 2015 przez Comandeer Guru (601,110 p.)

Zacznijmy od tego, że bez tego znacznika TO NIE JEST XML, bo jest niepoprawnie stworzony. Więc to zamknięcie powinno po prostu zostać dodane do pliku XML.

Co do znaczków na początku: po prostu zapisz plik w kodowaniu bez BOM.

komentarz 17 grudnia 2015 przez ScriptyChris Mędrzec (190,190 p.)

bez tego znacznika TO NIE JEST XML, bo jest niepoprawnie stworzony.

Faktycznie, w funkcji zapisującej plik do XML miałem zakomentowane dodanie na końcu znacznika </products>. Wyłączyłem też BOM ( https://github.com/eligrey/FileSaver.js/issues/160 ) i już DOMParser działa.

Dziękuję :)

0 głosów
odpowiedź 17 grudnia 2015 przez event15 Szeryf (93,790 p.)
Skoro to JS to czemu nie JSON?
komentarz 17 grudnia 2015 przez ScriptyChris Mędrzec (190,190 p.)
JSONa już robiłem. XML jest innym zadaniem, które też muszę zrobić. Zapisywanie działa, a przy odczycie mam w/w problem.

Podobne pytania

0 głosów
2 odpowiedzi 2,037 wizyt
+1 głos
1 odpowiedź 248 wizyt
0 głosów
2 odpowiedzi 208 wizyt
pytanie zadane 23 stycznia 2016 w C i C++ przez Kasia Nowicjusz (230 p.)

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...