Find all duplicate lines and display non matches - javascript

Is there an easy way to do this in javascript?
arr = ["red","blue","green","red","blue", "yellow"]
output = ["green", "yellow"]
Basically if a value is shown only once in an array output it. The order is random.
There are easy ways to do this in php, javascript is confusing me.
Need to run this on at least 4000 values, not sure what's faster, regex or array functions?
Thanks for any help.
code having problem with: myarrs values aren't accessible outside the function, I am stuck there. The file loads otherwise,
var txt = '';
var myarr = '';
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.status == 0 && xmlhttp.readyState == 4){
txt = xmlhttp.responseText;
myarr = txt.split("\n");
});
//alert(myarr.length);
xmlhttp.open("GET","list.csv",true);
xmlhttp.send();
var map = new Object();
for(var i = 0; i < myarr.length; i++)
{
if(map[myarr[i]] === undefined)
{map[myarr[i]] = 1; }
else
{map[myarr[i]]++; }
}
var result = new Array();
for(var i = 0; i < myarr.length; i++)
{
if(map[myarr[i]] > 1)
{ //do nothing
}
else
{result.push(myarr[i]);}
}
console.debug(result);
document.write(result);

If order of the unique elements doesn't matter, you can store the item in an object and increment the count, like this
var arr = ["red", "blue", "green", "red", "blue", "yellow"], obj = {};
arr.forEach(function(currentItem) {
obj[currentItem] = (obj[currentItem] || 0) + 1;
});
And then filter out all the items for which the value is not 1, to get the unique values
var unique = Object.keys(obj).filter(function(currentItem) {
return obj[currentItem] === 1;
});
console.log(unique);
# [ 'green', 'yellow' ]
Note: If you don't declare the variables with var keyword, they will become global properties.

var txt = '';
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
//for local files use status zero not 200
if(xmlhttp.status == 0 && xmlhttp.readyState == 4){
txt = xmlhttp.responseText;
myarr = txt.split("\n");
display = myarr.filter(function(a,b,c){return c.indexOf(a)===c.lastIndexOf(a);});
document.write(display);
// myarr.replace(",", "<br>");
}
};
xmlhttp.open("GET","list.csv",true);
xmlhttp.send();
The only thing I don't understand is why does the page keep trying to load after it finishes processing the whole file.

Related

Because I only see the last element of the for loop

I'm having a problem; I have the following program code:
var xmlhttp = new XMLHttpRequest();
var url = "https://wjko5k6250.execute-api.us-east-2.amazonaws.com/motorcycle";
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var allmot = JSON.parse(this.responseText);
console.log(allmot);
for(var i = 0, len = allmot.Items.length; i < len; i++)
{
id=allmot.Items[i].id
var url1 = "https://wjko5k6250.execute-api.us-east-2.amazonaws.com/motorcycle/"+id;
console.log(url1);
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
console.log(myArr);
document.getElementById("img").src = myArr.Item.image;
document.getElementById("brd").innerHTML = myArr.Item.brand;
}
};
xmlhttp.open("GET", url1, true);
xmlhttp.send();
}
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
allmot is as follows:
Items: Array (4)
0: {brand: 'Guzzi', id: '123456', image: 'moto_guzzi.jpg', date: '27/11/2021 '}
1: {brand: 'Bimota', id: '135623', image: 'bimota.jpg', date: '04/12/2021 '}
2: {brand: 'Ducati', id: '123789', image: 'b_desertx.jpg', date: ' 04/12/2021 '}
3: {brand: 'Benelli', id:' 146975 ', image:' benelli.jpg ', date: '27/11/2021'}
url1 returns (according to the for loop):
https://wjko5k6250.execute-api.us-east-2.amazonaws.com/articles/123456
https://wjko5k6250.execute-api.us-east-2.amazonaws.com/articles/135623
https://wjko5k6250.execute-api.us-east-2.amazonaws.com/articles/123789
https://wjko5k6250.execute-api.us-east-2.amazonaws.com/articles/146975
and so far everything seems to be fine.
The problem is in myArr; I noticed that it returns the image and brand of the last element only, so the one that has id equal to 146975.
Therefore there seems to be problems with the for loop.
Can anyone kindly help me? Thank you all.
As first correction I'd not recycle the XHR object from the outer loop in the inner loop.
When you say xmlhttp.onreadystatechange = function() ... in the inner loop, the xmlhttp is already in the readystate, obtained in the outer loop.
So, without further checking what is going on, I'd use two XHR objects (maybe like outerXmlhttp and innerXmlhttp). I'd also recreate the inner XHR for every cycle with:
var innerXmlhttp;
at the top of the outer closure.
Then, inside the cycle do:
innerXmlhttp = new XMLHttpRequest();
This is because of variable hoisting. If you just do this:
var innerXmlhttp = new XMLHttpRequest();
inside the cycle you may get a different behaviour. Just don't do it and write what you mean (hoist variables and assign them where you actually need it).
If all of this isn't enough ask a new, more precise question about what is going on.
This is your code with the corrections:
var outerXmlhttp = new XMLHttpRequest();
var url = "https://wjko5k6250.execute-api.us-east-2.amazonaws.com/motorcycle";
outerXmlhttp.onreadystatechange = function() {
var innerXmlhttp;
if (this.readyState == 4 && this.status == 200) {
var allmot = JSON.parse(this.responseText);
console.log(allmot);
for(var i = 0, len = allmot.Items.length; i < len; i++)
{
id=allmot.Items[i].id
var url1 = "https://wjko5k6250.execute-api.us-east-2.amazonaws.com/motorcycle/"+id;
console.log(url1);
innerXmlhttp = new XMLHttpRequest();
innerXmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
console.log(myArr);
document.getElementById("img").src = myArr.Item.image;
document.getElementById("brd").innerHTML = myArr.Item.brand;
}
};
innerXmlhttp.open("GET", url1, true);
innerXmlhttp.send();
}
}
};
outerXmlhttp.open("GET", url, true);
outerXmlhttp.send();
EDIT: #Teemu's eagle eye
As #Teemu points out in his comment, if you reassign values over and over to the same DOM objects like this:
document.getElementById("img").src = myArr.Item.image;
document.getElementById("brd").innerHTML = myArr.Item.brand;
you're clearly overwriting whatever value was there before. Instead, you should create and append those DOM objects, more like this:
var img = document.createElement("img");
img.src = myArr.Item.image;
var brd = document.createElement("p");
brd.innerText = myArr.Item.brand;
document.getElementById("motlist").append(img);
document.getElementById("motlist").append(brd);
Obviously, you'll need a <div id="motlist"></div> element or some other parent in the DOM to which to append the new elements.
For paging you may also want to clear those elements in the list... but here we're going overboard.

Get data from DataObject csv file javascript

I read a csv file using the code
var x="dema.csv";
loadCSV(x);
function loadCSV(file) {
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari
var request = new XMLHttpRequest();
} else {
// code for IE6, IE5
var request = new ActiveXObject('Microsoft.XMLHTTP');
}
// load
request.open('GET', file, false);
request.send();
parseCSV(request.responseText);
}
I put the data into a dataObject using this code
function parseCSV(data, dataArray) {
//replace UNIX new lines
data = data.replace(/\r\n/g, "\n");
//replace MAC new lines
data = data.replace(/\r/g, "\n");
//split into rows
var rows = data.split("\n");
// loop through all rows
for (var i = 0; i < rows.length; i++) {
// this line helps to skip empty rows
if (rows[i]) {
// our columns are separated by comma
var column = rows[i].split(",");
var date=column[0];
var value = column[4];
var dataObject = {
date: date,
T4: value
};
/
dataArray.push(dataObject);
}
}
}
I get only the date column and T4 column. my problem is that i wanna some way to do some processing ( for loops to verify some conditions (ex: T4 shouldn't surpass 700 over 30 s))
Can i do it only using a dataObject or use a 2D array? how can i get the cells content using the right tool?
var x = "dema.csv";
var dataArray = [];
loadCSV(x);
function loadCSV(x) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
parseCSV(this.responseText, dataArray);
// you can loop over the array like this
//dataArray.forEach((line) => {
// here line contains data, time, tops, cycle, T4, test
// you can access them like line.time, line.T4, line.tops etc
// console.log(line.time);
// console.log(line.tops);
// etc
//});
window.alert(dataArray[0].T4);
}
};
xhttp.open("GET", x, true);
xhttp.send();
}
function parseCSV(data, arr) {
//replace UNIX new lines
data = data.replace(/\r\n/g, "\n");
//replace MAC new lines
data = data.replace(/\r/g, "\n");
//split into rows
var rows = data.split("\n");
// loop through all rows
for (var i = 0; i < rows.length; i++) {
// this line helps to skip empty rows
if (rows[i] && i > 0) {
// our columns are separated by comma
var column = rows[i].split(",");
var dataObject = mapValuesToObj(column);
arr.push(dataObject);
}
}
}
function mapValuesToObj(csvLine) {
var absTime = csvLine[0];
var time = csvLine[1];
var tops = csvLine[2];
var cycle = csvLine[3];
var t4 = csvLine[4];
var test = csvLine[5];
return {
date: absTime,
time: time,
tops: tops,
cycle: cycle,
T4: t4,
test: test
};
}

Error parsing CSV 15 Rows In - Can't Figure Why - Neither Can My Friends

I am creating an interactive on student loan defaults. I am pulling the CSV from google sheets and parsing it with some code I wrote. I do a state name check which becomes arrayName and I push the data to that states array.
15 rows in I get arrayName.push is not a function...yet it worked for the data prior and the data has not changed format or type.
I am going to include the brief snippet and the csv link. If you would like the whole code download from the github link.
Thanks,
Michael
//Load CSV from Google Docs
function loadCSV() {
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 4 && xmlhttp.status==200){
var data = xmlhttp.responseText.toString();
dataArray = data.split(',');
console.log('data length: '+dataArray.length);
parseData(dataArray);
}
};
xmlhttp.open("GET",'http://cors.io/?u=' + url);
xmlhttp.send(null);
};
counter = 1;
arrayName = '';
function parseData(data){
for (var i = 0; i < data.length; i++) {
//Counter for doing statname check when it gets to new row
if (counter === 1) {
if (arrayName != data[i].toString().toLowerCase()) {
// Code for creating arrays will go here in future [...]
arrayName = data[i].toString().toLowerCase();
arrayName = eval(arrayName);
arrayName.push(data[i]);
counter++
} else { counter++ }
} else {
arrayName.push(data[i]);
counter++;
if (counter === 14) { counter = 1; };
}
console.log(data[i]);
};
console.log(data);
console.log(alabama);
};
loadCSV();
CSV
https://docs.google.com/spreadsheets/d/1n-XiUc1JdRZpAo-WDj6MleE6WcDDnZwqdbQk0rudbLw/pub?output=csv
Repo
https://github.com/mpaccione/Loan-Defaults
You are using split(','), which splits on every ',' - including those between quotes (see line 15)
dataArray = data.split(',');
line 15:
"700 PELHAM ROAD, NORTH"

JavaScript error with splitting string into array

I am running into an issue with splitting a string into an array. To help myself troubleshoot the problem, I included two alert() functions, but only one gets called. Therefore, I know that there is an issue splitting a string into an array (for a basic username/password check). Here is my JS code:
function check() {
var user = document.loginform.usr.value;
var pass = document.loginform.psw.value;
var valid = false;
var txt = new XMLHttpRequest();
var alltext = "";
var allLines = [];
var usrn = [];
var pswd = [];
txt.open("GET", "/c.txt", true);
alltext = txt.responseText;
allLines = alltext.split(/\r\n|\n/);
usrn = allLines[0].split(',');
alert("usrn split");
pswd = allLines[1].split(',');
alert("pswd split");
for (var i=0; i <usrn.length; i++) {
if ((user == usrn[i]) && (pass == pswd[i])) {
valid = true;
break;
}
}
if(valid) {
window.location = "test.html";
return false;
}else{
var div = document.getElementById("login");
div.innerHTML = '<font color="red" size=2><i>Invalid Username/Password!</i></font><br>' + div.innerHTML;
}
}
The file that contains the login credentials (c.txt) is as follows:
User1,User2
pass,password
When User1 enters his/her name into the form, the password should be "pass". However, the script gets stopped at "pswd = allLines[1].split(',');". Am I misunderstanding the lines array?
Any help is appreciated - thanks!
You need to either use a synchronous call by changing the line to
txt.open("GET", "/c.txt", false);
Or use the "onreadystatechange" event to get the response when the server returns it
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
alltext = txt.responseText;
allLines = alltext.split(/\r\n|\n/);
usrn = allLines[0].split(',');
alert("usrn split");
pswd = allLines[1].split(',');
alert("pswd split");
for (var i=0; i <usrn.length; i++) {
if ((user == usrn[i]) && (pass == pswd[i])) {
valid = true;
break;
}
}
if(valid) {
window.location = "test.html";
return false;
}else{
var div = document.getElementById("login");
div.innerHTML = '<font color="red" size=2><i>Invalid Username/Password!</i></font><br>' + div.innerHTML;
}
}
}
You need to call txt.send(). Also it is async so txt.responseText will most likely be null.
You can use onreadystatechanged like so to ensure that txt.responseText has a value:
txt.onreadystatechange = function() {
if (txt.readyState == 4) { // 4 = DONE
alert(txt.responseText);
}
}
Okay - after fiddling with the code and doing some more research, I got a working script. This script takes data from a form and checks it against a file (c.txt). If the form entries match a username/password combination in c.txt, it takes you to another webpage.
function check() {
var user = document.loginform.usr.value;
var pass = document.loginform.psw.value;
var valid = false;
var txt;
if(window.XMLHttpRequest){
txt = new XMLHttpRequest();
}else{
txt = new ActiveXObject("Microsoft.XMLHTTP");
}
var allLines = [];
var usrn = [];
var pswd = [];
txt.onreadystatechange=function() {
if(txt.readyState==4 && txt.status==200){
var alltext = txt.responseText;
allLines = alltext.split(/\r\n|\n/);
usrn = allLines[0].split(',');
pswd = allLines[1].split(',');
for (var i=0; i <usrn.length; i++) {
if ((user == usrn[i]) && (pass == pswd[i])) {
valid = true;
break;
}
}
if(valid) {
window.location = "test.html";
return false;
}else{
var div = document.getElementById("login");
div.innerHTML = '<font color="red" size=2><i>Invalid Username/Password!</i></font><br>' + div.innerHTML;
}
}
}
txt.open("GET", "c.txt", false);
txt.send();
}

Add data to local array in javascript

I've been trying to add data into my array for sometime now and it doesn't work. I have the following code:
function OBJMesh(file)
{
this.modelVertex = [];
this.modelColor = [];
var that = this;
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState == 4)
{
if(rawFile.status === 200 || rawFile.status === 0)
{
var allText = rawFile.responseText;
var lines = allText.split("\n");
for(var i = 0; i < lines.length; i ++)
{
var lineData = lines[i];
var lineString = lineData.split(" ");
if(lineString[0] === "v")
{
var x = parseFloat(lineString[1]);
var y = parseFloat(lineString[2]);
var z = parseFloat(lineString[3]);
/*
this.modelVertex.push(x);
this.modelVertex.push(y);
this.modelVertex.push(z);
this.modelColor.push(0.0);
this.modelColor.push(0.0);
this.modelColor.push(0.0);
this.modelColor.push(1.0);
*/
that.modelVertex.push(10.0);
//document.getElementById("textSection").innerHTML = "testing";
}
}
}
}
}
rawFile.send();
}
OBJMesh.prototype.getModelVertex = function ()
{
return this.modelVertex;
};
OBJMesh.prototype.getModelColor = function ()
{
return this.modelColor;
};
If I comment out the this.modelVertex.push(10.0); it gets pass the error and prints out "testing". But if I uncomment it, it gets stuck there and won't print anything out. Why is it doing this? how can I solve it so it actually pushes the given data to the this.modelVertex array?
Many Thanks
Edit: I have edited my code after dystroy told me what to do and it do work when I try to print the values in the OBJMesh constructor (shown above), but when I try to do this by creating the object in my main function (shown below) it doesn't print anything.
var cubeModel;
function main()
{
cubeModel = new OBJMesh("file:///Users/Danny/Desktop/3DHTMLGame%202/cube.obj");
document.getElementById("textSection").innerHTML = cubeModel.getModelVertex();
}
this isn't your new instance of OBJMesh in the callback but the XMLHttpRequest.
Start by referencing the desired object just before defining the callback :
var that = this;
rawFile.onreadystatechange = function ()
then use it :
that.modelVertex.push(10.0);
Answer to the question in your edit :
Your constructor contains an asynchronous request. Which means your array isn't available immediately but later.
A solution would be to pass a callback to the constructor :
function OBJMesh(file, doAfterInit) {
this.modelVertex = [];
this.modelColor = [];
var that = this;
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function () {
if(rawFile.readyState == 4)
{
if(rawFile.status === 200 || rawFile.status === 0)
{
var allText = rawFile.responseText;
var lines = allText.split("\n");
for(var i = 0; i < lines.length; i ++)
{
var lineData = lines[i];
var lineString = lineData.split(" ");
if(lineString[0] === "v"){
that.modelVertex.push(10.0);
if (doAfterInit) doAfterInit();
}
}
}
}
}
rawFile.send();
}
...
cubeModel = new OBJMesh("file:///Users/Danny/Desktop/3DHTMLGame%202/cube.obj", function() {
document.getElementById("textSection").innerHTML = cubeModel.getModelVertex();
});
But having a class here doesn't look like a smart idea.

Categories

Resources