How can I deal with this kind of bug in Javascript? [duplicate] - javascript

This question already has answers here:
How could I manipulate this array in Javascript for this kind of error checking?
(4 answers)
Closed 8 years ago.
How can I make sure that two commas are not entered in an Array .. this is for a web application that generates an array from user input and it's a text field .. I cant change it to anything else.
example .. var names=["Kim",,"Andrew","Ashley"];
in this array , we have two consecutive commas, instead of one .. how can i make sure that if the user enters any character that wouldn't be good , I just take it out .. like comma , dot, etc .. for the example of the extra comma , how would this be achieved considering that I have no other option but deal with a text field generating an array like this

Run the array through a function (see below) to remove the invalid values in your array. In your case, the values are undefined for the second element in ["Kim",,"Andrew","Ashley"].
var stripEmpty = function (ary) {
var result = [];
for (var i = 0; i < ary.length; i++) {
if (ary[i] !== undefined) {
result.push(ary[i]);
}
}
return result;
};
Then you can do this:
var names = ["Kim",,"Andrew","Ashley"];
var strippedNames = stripEmpty(names); // ["Kim","Andrew","Ashley"]
See working fiddle: http://jsfiddle.net/amyamy86/LymAZ/

Two consecutive commas (or a leading comma) is an elision, it increments the index of the next member. The elided member doesn't exist as a property of the array. To find such members, you can use the in operator:
var a = [,0,1,, , ,2,3,, ,];
var i = a.length;
while (i--) {
if (!(i in a)) { // returns true if a has no index i
a.splice(i, 1);
}
}
alert(a); // 0,1,2,3
This also deals with extra spaces in the array literal.

This isn't a bug per say, it's just that you are having null entries from your form being added to your array. try this:
//assume your array has been filled up
var mod_names = names.join("#"); // you can use any delimeter apart from '#'
if(mode_names.indexOf(" ") > -1){
mode_names.replace(/\s+/gi, "");
}
mode_names.replace(/#/gi, " ");
mod_names = mod_names.split(); // the default is a space char
names = mode_names;

Related

How to detect duplicate characters in an Array, and create an argument accordingly?

Good evening, I attempting to detect duplicate characters in a string. More specifically, I am trying to find up to two different duplicates within an Array. If there is one duplicate, add a sub-string, and if there is another duplicate, add a different sub-string. Is there any way to do this?
Here is some example code I have so far:
var CodeFieldArray = ["Z80.0", "Z80.1", "Z80.0", "Z70.4"];
/* We have an array here used to create the final string at the end of the
code. It is a dummy array with similar variables in my actual code. For
reference sake, there may be only one object in the array, or 7 total,
depending on the user's input, which is where the duplicate detection should
come in, in case the user enters in multiples of the same code. */
var i, Index;
for (i = 0, L = 0; i < CodeFieldArray.length; i++) {
Index = CodeFieldArray[i].indexOf(CodeFieldArray[i]);
if(Index > -1) L += 1;
Extra0 = CodeFieldArray.indexOf("Z80.8");
Extra1 = CodeFieldArray.indexOf("Z80.9");
if(L >= 2 && Extra0 == -1) CodeFieldArray.push("Z80.8");
Extra0 = CodeFieldArray.indexOf("Z80.8");
if(L >= 4 && Extra0 != -1 && Extra1 == -1) CodeFieldArray.push("Z80.9");
console.println(Extra0);
}
/*^ we attempted to create arguments where if there are duplicates
'detected', it will push, "Z80.8" or, "Z80.9" to the end of the Array. They
get added, but only when there are enough objects in the Array... it is not
actually detecting for duplicates within the Array itself^*/
function UniqueCode(value, index, self) {
return self.indexOf(value) === index;
}
CodeFieldArray = CodeFieldArray.filter(UniqueCode);
FamilyCodes.value = CodeFieldArray.join(", ");
/* this is where we turn the Array into a string, separated by commas. The expected output would be "Z80.0, Z80.1, Z70.4, Z80.8"*/
I have it to where it will add "Z80.8" or "z80.9" if they are not present, but they are being added, only if there are enough objects in the Array. My for-loop isn't detecting specifically the duplicates themselves. If there was a way to detect specifically the duplicates, and create an argument based off of that, then we would be doing grand. The expected output would be "Z80.0, Z80.1, Z70.4, Z80.8"
You can use Set and forEach and includes
var CodeFieldArray = ["Z80.0", "Z80.1", "Z80.0", "Z70.4"];
let unique = [...new Set(CodeFieldArray)];
let match = ['Z80.8','Z80.9'];
let numOfDup = CodeFieldArray.length - unique.length;
if(numOfDup){
match.forEach(e=>{
if(!unique.includes(e) && numOfDup){
unique.push(e);
numOfDup--;
}
})
}
console.log(unique.join(','))
So the idea is
Use Set to get unique values.
Now see the difference between length of original array and Set to get number of duplicates.
Now will loop through match array and each time we push item from match array into unique we reduce numOfDup by so ( to handle case where we have only one duplicate or no duplicate ).
In the end join by ,
You could do something like this:
var uniqueArray = function(arrArg) {
return arrArg.filter(function(elem, pos,arr) {
return arr.indexOf(elem) == pos;
});
};
uniqueArray ( CodeFieldArray )

Apps Script JS adding items to array from range (if not already in array) fails

I am looping through various cells and want to add their string content do an array, if the content is not already in the array. It works perfectly fine when I do it manually like so, trying to add 'eJobs' to the array (see below "var item = 'eJobs') which already containts 'eJobs':
var divisionarray = ['eJobs']
for (var i = 0; i < cells_users.length-1; ++i) {
var row_users = cells_users[i];
if (row_users[0] == user_ldap) {
var podarray = row_users[1].split(', ')
for (j = 0; j < podarray.length; j++) {
for (var k = 0; k < cells_edit.length; ++k) {
var row_edit = cells_edit[k]
if (podarray[j] === row_edit[0]) {
var item = 'eJobs'
if (!(divisionarray.indexOf(item) >= 0)) {
divisionarray.push(item)
}
}
}
}
Logger.log(divisionarray)
As expected, the log file shows [17-10-08 19:11:04:111 BST] [eJobs], illustrating that the code works and 'eJobs' has not been added to the array as it is already in the array.
Now, when I change var item='eJobs' to values of a range
var item = sheet_pods_edit.getRange(startRow+k, startColumn+1).getValue();
the code does not work anylonger, as the log file shows:
[17-10-08 19:14:03:770 BST] [eJobs, eJobs, BestJobs, Vivre Deco, ...
Note I have a range of thousands of cells, so I get alot of duplicates added. What am I missing? Note the cells of the defined range are indeed just strings with a single word (e.g. 'eJobs').
The code is working and the log file is indicating what the problem is..
[eJobs, eJobs, BestJobs, Vivre Deco,
In the second eJobs there is a white space before eJobs, so the first value and the second value don't match.
Without seeing your data and going by the 'just strings with a single word' I would say that using a .replace(" ", "") on the text string should work, this will find the first " " in the string and remove it. I.e. " eJobs" would become "eJobs".
2.
Is this line of code just for testing? You should never use a method like this in a script. It will be extremely inefficient
var item = sheet_pods_edit.getRange(startRow+k, startColumn+1).getValue();
Instead get the full range using .getValues()and iterate over it then.
3.
Is there a reason you are using === in if (podarray[j] === row_edit[0]) unless you need to check for type always use ==

Javascript Get Multiple Substrings Within One String

how to get multiple occurences of words in a string. I've tried multiple functions but with no success. I know I can get back the first true value using some() method as below.
var keyword_array = ["Trap","Samples","WAV","MIDI","Loops"];
function validateContentKeywords(content,keyword){
keyword.some(function(currentValue,index){
console.log(currentValue + " ");
return content.indexOf(currentValue) >= 0;
});
}
// Outputs --> Trap Samples
if(validateContentKeywords("Beat Loops WAV Trap Samples Dog Cat MIDI",keyword_array)){
console.log("Matches");
}
// What I Want is --> Trap,Samples,MIDI,Loops
The above function only outputs 2 occurences and I want it to output all of the matching values at the same time such as --> Trap,Samples,MIDI,Loops.
Is there a way to get multiple occurences of words in a string at the same time?
UPDATED:: The solution that helped me out is below
function Matches(value){
return "Beat Loops WAV Trap Samples Dog Cat MIDI".indexOf(value) !== -1;
}
var keyword_array = ["Trap","Samples","WAV","MIDI","Loops"].filter(Matches);
document.write(keyword_array);
You seem to be looking for the filter Array method that returns an array of the matched elements, instead of an boolean value whether some matched.
var keyword_array = ["Trap", "Samples", "WAV", "MIDI", "Loops"];
function validateContentKeywords(content, keyword) {
var words = content.split(' '); //split the given string
for (var i = 0; i < words.length; i++) {
if (keyword.indexOf(words[i]) > -1) { //check if actually iterated word from string is in the provided keyword array
document.write(words[i] + " "); //if it is, write it to the document
};
}
}
validateContentKeywords("Beat Loops WAV Trap Samples Dog Cat MIDI", keyword_array);
The easiest way to do it would be this:
keyword_array.filter(keyword => searchString.includes(keyword));
You can learn more about filter here. I highly recommend learning about how to use map, reduce and filter. They are your best friends.

How to identify pairs in a string

Suppose I have the string : "((a,(b,c)),(d,(e,(f,g))))"
How would I go about extracting each pair separately such as splitting the first pair and extracting (a,(b,c)) and (d,(e,(f,g))).
I am kind of lost as to how I should approach this. Since the pairs can vary as the example I can't exactly look for a set pattern.
I believe an approach to this would be identifying where the "," is in the outer most parentheses. such as finding it in ( (set of pairs 1) , (set of pairs 2)).
so I can then be able to take everything left of it and right of it. But I do not know how to do this. Using str.Indexof() will take the first occurrence of "," which is not the one I am interested in.
I would loop through the string's characters keeping track of how nested the parentheses are, to find the first comma that isn't nested, and then (as you said) take the parts to the left and right of that:
function getPairs(input) {
// remove outer parentheses, if present
if (input[0] === "(")
input = input.slice(1,-1);
// find first comma that isn't inside parentheses
var parenNestLevel = 0;
for (var i = 0; i < input.length; i++) {
if (parenNestLevel === 0 && input[i] === ",")
return [input.slice(0, i), input.slice(i+1)];
else if (input[i] === "(")
parenNestLevel++;
else if (input[i] === ")")
parenNestLevel--;
}
// note: returns undefined if the input couldn't be parsed
}
var input = "((a,(b,c)),(d,(e,(f,g))))";
var pairs = getPairs(input);
console.log(pairs);
console.log(getPairs(pairs[0]));
For your input, that would return the array ["(a,(b,c))", "(d,(e,(f,g)))"], and you could then run getPairs() on the parts of the returned array, or make it recursive, or whatever - you don't really make it clear what the final output should be from your sample "((a,(b,c)),(d,(e,(f,g))))" input.
Here is a simpler solution. We first remove the first and last parenthesis, then split the resulting string with '),(', then iterate over the result and prepend/append the missing parenthesis to individual elements depending on their position:
var a = "((a,(b,c)),(d,(e,(f,g))))";
var b = a.substring(1,a.length-1); //remove first and last parenthesis
var c = b.split('),('); //get pairs
for(var i=0;i<c.length;i++){
if(i%2===0){
c[i] = c[i]+')';
}else{
c[i] = '('+c[i];
}
}
console.log(c); // ["(a,(b,c))", "(d,(e,(f,g)))"]

Jquery- How to remove comma after a specific record in an array [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 8 years ago.
Improve this question
I am using the datatables mRender function to generate a list of items in a column separated by commas. I wanted to remove a specific record from the list and the record lies at the end of list of records in an array. Something like this:
LESS,SAAS,REST,API
I want to remove the last record (API, which i did), however, when i remove it the comma still sticks to it at the end, resulting into something like:
LESS,SAAS,REST,
LESS,SAAS,
assuming that all time the record after the comma is the ALL. How can i remove the record and also the comma that sticks after it??
EDIT: This is how i have the code and im removing the API, by passing empty string. Please suggest of this could be done better.
mRender: function (obj) {
_.each(obj, function(item, index){
var prodVal = "";
else if (item === 'API'){
prodVal = '';
}
returnVal.push("<span class='product'>" + prodVal + "</span>");
});
return returnVal.join(', ');
}
Any ideas???
Thanks!
Removing the last element
Depending on whether you're working with an array, object, or string, there are a few different ways to handle it. With your example, it looks like your setting the value to empty, rather than removing the entry, which is why you're getting an extra comma after using returnVal.join(', ').
Remove last element from array
var mRecord = ["LESS","SAAS","REST","API"];
mRecord.pop();
console.log(mRecord); // Array( [0] => "LESS", [1] => "SAAS", [2] => "REST" )
console.log(mRecord.join()); // String "LESS,SAAS,REST"
Remove last element from string
// with simple built-in functions - will perform better in your example
mRecord = mRecord.substring(0, str.lastIndexOf(",") - 1);
// with regex - may perform better with larger strings
mRecord = mRecord.replace(/,[^,]+$/, "");
Remove the last member of an object
While I am uncertain as to the structure of the object you are working with, you should likely be using some variation of delete mRecord[member].
Currently, prodVal = '' leaves the entry in the array, causing returnVal.join(', ') to include an extra ', ' between the last value, and the empty one.
Your code includes an else if but not the initial if declaration. I suspect that if you move the push and returns within the main conditional, it may work as you intend
mRender: function (obj) {
_.each(obj, function(item, index){
var prodVal = "";
if (item === 'API'){
prodVal = '';
// edit: your best bet is to generate a new array or object to act on
// rather than trying to unset the item here.
} else {
returnVal.push("<span class='product'>" + prodVal + "</span>");
}
});
return returnVal.join(', ');
}
use this
var str = "LESS,SAAS,REST,API";
var res = str.split(",");
res.pop();
console.log(res.join(","));
explode into array i.e. var arr = 'LESS,SAAS,REST,API'.split(',')
remove element i.e. av.splice(av.length-1,1); //<- removes last element
Join again to generate string av.join(',')
var list = 'LESS,SAAS,REST,';
list = list.substring(0, list.length);
There are many ways to do this, but I think that splitting the string into an array, filtering out the array, and then joining back into a string will be the most robust & flexible.
Something like this:
var items = 'LESS,SAAS,REST,API'.split( ',' );
items = items.filter(function( item ) { /* return false for anything you want to remove */ });
console.log( items.join( ',' ) );
A few relevant links:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join
this will remove the 7 from this example array showing how the splice works
var anArray = [ "1", "2", "3", "4", "5", "6", "7" ];
anArray.splice(-1);
will give 123456 (without the 7 the last element in the array)
here is a jsfiddle showing it in action
This is a very simple function exactly for what you need. Try it out and let me know what you think:
$(document).ready(function() {
var string = "LESS,SAAS,REST,API";
var array = string.split(",");
function delete_last(elem) {
var index = array.indexOf(elem);
array.splice(index, 1);
return array.join(",");
}
var results = delete_last("API");
console.log(results);
});

Categories