JavaScript: Detecting duplicate elements in an array [closed] - javascript

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have a small script that should detect duplicate elements in an array of fields on a form.
function dupes() {
var unique = [];
//Loop through array of fields to get entered values
for (i = 0; i <= 9; i++) {
unique[i] = Number(document.getElementById('proj' + i).value);
}
unique.sort();
//Now compare the array values. If there are any duplicates, throw an error
for (i = 1; i <= 9; i++) {
if (unique[i] == unique[i - 1]) {
document.getElementById('errormsg').innerHTML = 'duplicated values!';
return false;
}
}
}
There are ten of these "proj" fields (proj0 - proj9), and I have an onClick event assigned to call this function. If there are any duplicate values, the span 'errormsg' is supposed to display an error, but it's not working. What might I be missing?

//Check for duplicate project numbers
function errorCheck() {
var unique = [];
//Loop through array of fields to get entered values
for (i = 0; i <= 9; i++) {
var currentValue = Number(document.getElementById('projNo' + i).value);
if(unique.indexOf(currentValue)!=-1)
{
document.getElementById('projError').innerHTML = 'duplicated values!';
return false;
}
unique[i]=currentValue;
}
return true;
}
FiddleDEMO
It first checks whether a value is already in the array by using unique.indexOf(currentValue). This function returns the index of the searched element and returns -1 if it is not found.
If it was not found, it adds it to the array and goes to the next one.
Edit:
If you want to reset the error message when you submit again and there are no more duplicates, don't forget to reset it before return true; like so:
document.getElementById('projError').innerHTML = 'no duplicates ;)';

This will detect the duplicate values :
var arr= [];
//Loop through array of fields to get entered values
for (i = 0; i <= 9; i++) {
arr.push(Number(document.getElementById('proj' + i).value));
}
function dupes(arr) { // pass the array to find dupes
var i, len=arr.length, unique= [], obj={};
for (i=0;i<len;i++) {
obj[arr[i]]=0;
}
for (i in obj) {
unique.push(i);
}
if(unique.length != arr.length) {
document.getElementById('errormsg').innerHTML = 'duplicated values!';
}
}
dupes(arr);

Related

javascript - if else not resulting in expected comparision [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am new to javascript. I am having a little issue here.
Is javascript if / else statement different than other languages (c++, java, python)?
Here is the issue that I am having.
if else statement only accepts i == 0 and i == 1 into my new array from myArray.
Why am I not be able to separate other elements into my new array? I used myArray for an example. In my real problem, I wouldn't know how many elements I have. That is why I have set up variables threetimes and increaseByThree. I am just trying to separate name, zip code, and amount into the different array by using a for loop.
var nameArray = [], zipCodeArray = [], totalAmountArray = [];
var threeTimes = 3;
var increaseByThree = 0;
var myArray = ["Eric ", "94990", "540", "Sam ", "303030", "350"];
for(var i = 0; i < myArray.length; i++) {
threeTimes += 3;
increaseByThree += 3;
if(i == threeTimes || i == 0) {
nameArray.push(myArray[i]);
} else if(i == increaseByThree || i == 1) {
zipCodeArray.push(myArray[i]);
} else {
totalAmountArray.push(myArray[i]);
}
}
console.log(nameArray)
console.log(zipCodeArray)
console.log(totalAmountArray)
Assuming your array will be in the format [a0, b0, c0, ....., aN, bN, cN] where N is the number of 'entries' - 1; you could simplify your logic that you determine where to put the value by:
const myArray = ["Eric ", "94990", "540", "Sam ", "303030", "350"];
const nameArray = [], zipCodeArray = [], totalAmountArray = [];
for(var i = 0; i < myArray.length; i++) {
switch (i % 3) {
case 0:
nameArray.push(myArray[i]);
break;
case 1:
zipCodeArray.push(myArray[i]);
break;
case 2:
totalAmountArray.push(myArray[i]);
break;
}
}
console.log(nameArray)
console.log(zipCodeArray)
console.log(totalAmountArray)
This will work for any size array and cuts out the need for the unnecessary variables and if-else blocks. Here is a helpful link for javascript's switch block
(https://www.w3schools.com/js/js_switch.asp) which are much cleaner as opposed to if-else blocks and show the intent more clearly in this case.

Elegant method to compare an array of strings to another array of strings [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Question: How can I elegantly compare an array of strings to another array of strings thus returning an array of non-matching strings
var master = ['1','2','3','4']
var versioned = ['1a','2','3b','4']
var errorLog = []
var count = 0;
//this for loop doesn't work :(
for(var i = 0; i < versioned.length - 1; ++i ){
for(var j = 0; j < master.length -1; ++j){
if(versioned[i] === master[j]){
console.log('cleared');
}
if(count === master.length){
errorLog.push(versioned[i]);
}
}
}
loop will return ['1a', '3b'];
I feel like filter() or map() or reduce() will do this but I'm unable to wrap my brain around this properly.
var master = ['1','2','3','4'];
var versioned = ['1a','2','3b','4'];
function diff(needle, haystack){
return needle.filter(function(item){
return !~haystack.indexOf(item);
});
}
console.log(diff(versioned, master)); //["1a", "3b"];
~ NOTing any number equals -(x + 1). so ~-1 becomes 0, which is the only falsy.
~master.indexOf(item) is the same as master.indexOf(item) !== -1

Improving performance while iterating two nested loops [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I calculate a "Top-5-List" of Birthplaces organized in an array of objects in this form
var myObjArr =[
{
"birth":
{
"year": 2012,
"name": "Manchester, Vermont, USA",
}
} , (and so on)
];
My approach however does not seem to be much performant:
for (var i = 0; i < myObjArr.length; i++) {
var alreadyListed = -1;
for (var j = 0; j < resultData.length; j++) {
if(resultData[j].key == myObjArr[i]['birth']['name']) { // birthname already in resultData
alreadyListed = j;
break;
}
}
if(alreadyListed != -1 ) { // birthname already in resultData -> raise count
resultData[alreadyListed].count += 1;
}else { // birthname not yet in resultData -> add to resultData
resultData.push({key: myObjArr[i]['birth']['name'], count: 1 });
}
}
}
Neiter javascript's forEach nor angulars angular.forEach seem to improve the performance. Any Suggestions?
You can use an object as a dictionary instead of using an array and looking for a key by iterating, this way the second "loop" is done by the Javascript implementation when looking for object keys (also it's probably not a linear scan but an hash table lookup):
var result = {};
myObjArr.forEach(function(obj) {
var key = "!" + obj.birth.name;
result[key] = 1 + (result[key] || 0);
});
I'm always adding a "!" in front of the key when using objects as dictionaries because all Javascript objects do have an inherited constructor property and I don't want to interfer with that.
The (x || 0) trick is to start with a 0 when a name has not seen before (undefined is falsy in Javascript). Adding 1 to undefined instead results in NaN.
If you really need an array as result the code is only slightly more complex:
var result = [];
var index = {};
myObjArr.forEach(function(obj) {
var key = "!" + obj.birth.name;
var ix = index[key];
if (ix === undefined) {
// Allocate a new entry
index[key] = result.length;
result.push({key:key, count:1});
} else {
result[ix].count += 1;
}
});

For loop Jquery creating table [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have been trying to create a table dynamically based on an array return from another function.
I have 2 array :
var listOfNames = ['a', 'b', 'c'];
var scoreLabels = ['Query', 'Entry', '% Matched', 'Alignment Len', 'Mismatches', 'Gaps', 'E-Value', 'Bitscore'];
The first array will contain element which will be id of each row.
The second array is the list of columns for each row.
My html looks like this
<table>
<tbody></tbody>
</table>
and the for loop that I have written looks like this :
for (var i = 0; listOfNames.length < i; i++) {
var row = $('<tr></tr>');
$(row).attr('id', listOfNames[i]);
for (var x = 0; scoreLabels.length < x; x++) {
var tableHeader = $('<td></td>');
$(tableHeader).attr('text', scoreLabels[x]);
$(tableHeader).appendTo(row);
}
$(row).appendTo('table');
}
I have been looking at other posts that teaches the creation of table dynamically with jquery, but to no avail.
Please kindly advice and let me know where i went wrong .
The js fiddle can be found here
http://jsfiddle.net/t16scofy/2
For-loops...
Just read your for-loops out loud:
for (var i = 0; listOfNames.length < i; i++) {...}
becomes:
for i - starting at 0 - do ... as long as the length of listOfNames is smaller then i.
I starts at 0. and the length of listOfNames is always larger then 0. It is never smaller. so this for loop will never do ...
Same goes for you inner for-loop
corrected:
for (var i = 0; i < listOfNames.length; i++) {...}
or if you really want the i after the .length:
for (var i = 0; listOfNames.length > i; i++) {...}
You have a few typos and wrong conditions in both your for loops.
This should do it:
var listOfNames = ['a', 'b', 'c'];
var scoreLabels = ['Query', 'Entry', '% Matched', 'Alignment Len', 'Mismatches', 'Gaps', 'E-Value', 'Bitscore'];
// If i starts with 0, and you're incrementing it, you obviously want the loop
// to go until it reaches a bigger value, not the other way round.
for (var i = 0; i < listOfNames.length; i++) {
var row = $('<tr>', { class: i.toString() });
// If x starts with 0, and you're incrementing it, you obviously want the loop
// to go until it reaches a bigger value, not the other way round.
for (var x = 0; x < scoreLabels.length; x++) {
var tableHeader = $('<td>', { text: scoreLabels[x] });
tableHeader.appendTo(row);
}
row.appendTo('table');
}
Demo

How can I print using `document.getElementByID("results").innerHTML = results? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
When I click the roll button, nothing happens. Is there a way to show the results using document.getElementByID("results").innerHTML, or is this not recommended?
HTML
<p>How many dice?
<br/>
<input type="text" id="numDice" />
</p>
<p>How many sides per die?
<br/>
<input type="text" id="numSides" />
</p>
<button onclick="diceRoll()" id="roll"/>Roll!</button>
<p id="results"></p>
JavaScript
var numDice = document.getElementByID(numDice).innerHTML;
var numSides = document.getElementByID(numSides).innerHTML;
function diceRoll() {
var results = "";
for (var i = 0; i < numDice; i++) {
results += (Math.random() * numSides) + 1;
}
document.getElementByID("results").innerHTML = results;
}
CodePen
Typo, it's not
getElementByID
but
getElementById
The case is important, and the arguments passed are strings, so they should be quoted
function diceRoll() {
var numDice = document.getElementById('numDice').value;
var numSides = document.getElementById('numSides').value;
var results = "";
for (var i = 0; i < numDice; i++) {
results += (Math.round(results + (Math.random() * numSides) + 1)).toString();
}
document.getElementById('results').innerHTML = results;
}
FIDDLE
You are calling document.getElementByID(numDice).innerHTML before the DOM is ready. The element does not exist, so this will throw an error.
You want to get the values each time diceRoll() is called, so that you get the values the user entered. numDice will not automatically update when the value changes.
P.S. It's getElementById, and you want to use .value() for <input>s.
function diceRoll() {
var results = "";
var numDice = parseInt(document.getElementById('numDice').value, 10);
var numSides = parseInt(document.getElementById('numSides').value, 10);
for (var i = 0; i < numDice; i++) {
results += (Math.random() * numSides) + 1;
}
document.getElementById("results").innerHTML = results;
}

Categories