indexOf in an array not behaving correctly - javascript

I'm attempting to use JS to check a string for the most amount of the letters and append that result to a div. It looks so far like this:
var string = "AABBCCDDEEEEEEEEEE";
var stringInput = document.getElementById("string");
function showMostChar() {
var newInput = string.split("");
var inputAsArray = Array.of(newInput);
for (i = 0; i > inputAsArray; i++) {
if ((inputAsArray.indexOf("E")) > 9 ) {
stringInput.innerHTML = "E";
}
}
}
window.onload = showMostChar;
<div id="string"></div>
In plain english, I'm looking to split a string by character, which I then use to create an array. I loop through the array and if E has more than 9 (an arbitrary value) put E into the div. before I was using array() but I remembered thats not a valid function, so I did research and found Array.of() but I'm not seeing anything appended to string div.
is Array.of() not the right way to create an array in this context? If not why?
The ideal scenario is to log the total amount of characters that appear the most, so in this instance EEEEEEEEEE. I need to somehow get the value of each character and compare it to each other, somehow...something like:
for (i = 0; i > inputAsArray; i++) {
// somehow compare values to each other? e being each instance
// so, would that be a loop within a loop?
if ((i.value()) > e ) {
stringInput.innerHTML = i;
}
}

There are few things that needs to be fixed in your code:
First of all .split() will return an array so newInput is
already an array, you don't need any transform it.
In the other hand the right method to create a new array is
Array.from(), because Array.of() takes a Number as
argument.
Second thing you don't need any loop to check for the .indexOf(), you can directly call it upon newInput array.
And it wasn't entering the if block because .indexOf() will return
the first index of E in the array, which is lower than 9, I
used 5 for testing purpose here.
This is how should be your code:
function showMostChar() {
var newInput = string.split("");
if ((newInput.indexOf("E")) > 5 ) {
stringInput.innerHTML = "E";
}
}
Demo:
var string = "AABBCCDDEEEEEEEEEE";
var stringInput = document.getElementById("string");
function showMostChar() {
var newInput = string.split("");
console.log(newInput);
if ((newInput.indexOf("E")) > 5) {
stringInput.innerHTML = "E";
}
}
window.onload = showMostChar;
<div id="string"></div>
Edit:
To get the number of occurrences of E in the array, you can use Array.filter() like this:
function getNumberOfOccurences(char) {
var newInput = string.split("");
return newInput.filter(function(c){
return c === char;
}).length;
}
console.log(getNumberOfOccurences("E"));
Demo:
var string = "AABBCCDDEEEEEEEEEE";
var stringInput = document.getElementById("string");
function getNumberOfOccurences(char) {
var newInput = string.split("");
return newInput.filter(function(c){
return c === char;
}).length;
}
console.log(getNumberOfOccurences("E"));

Related

How to remove function name from Javascript object

I have a Leaflet map and I want to edit a polygon. I successfully do this, but when I finish the editing, the coordinates are saved like:
,,LatLng(44.94633, 26.00773),LatLng(44.93588, 25.94318),LatLng(44.94245, 25.90645),LatLng(44.91814, 25.87074),LatLng(44.91328, 25.9346),LatLng(44.90015, 25.97031),LatLng(44.90112, 26.11519)"
I only want to have the coordinates without function name. How can I do this? Thanks!
map.on("dragend", function(e){
poligon = polygon.getLatLngs();
poligon1 = poligon.toString();
$('#geo').val(poligon1);
console.log(poligon1);
});
Dont use toString() u will get an array of objects
var arr=[];
console.log(polygon.getLatLngs());
for(var i=0;i<arr.length;i++){
arr=polygon.getLatLngs();
console.log(arr[i].lat);
console.log(arr[i].lng);
console.log("("+arr[i].lat +","+arr[i].lng+")");
}
Resolved it by writing one line:
poligon = polygon.getLatLngs();
//this is what I added
poligon2=poligon.join(',').match(/([\d\.]+)/g).join(',')
You can override toString method of LatLng prototype at your project init
L.LatLng.prototype.toString = function() {
return '(' + this.lat + ',' + this.lng + ')';
}
Then you'll see output like this cause Array.toString() recursively call toString() on every element in collection.
(44.94633, 26.00773),(44.94633, 26.00773)
I'll just add an answer.
This should work in general: give it a string, it will try to find all numbers, and return them in an array.
<script>
var mystring = "LatLng(44.94633, 26.00773),LatLng(44.93588, 25.94318),LatLng(44.94245, 25.90645),LatLng(44.91814, 25.87074),LatLng(44.91328, 25.9346),LatLng(44.90015, 25.97031),LatLng(44.90112, 26.11519)";
function isNumeric(input) {
return (input - 0) == input && input.length > 0;
}
// reads a string, finds numbers (float), returns the numbers in an array
function numbersInString(string) {
var s = 0, temp=0, result = [];
for(var i=0; i<string.length; i++) {
s = string.substr(i,1); // search 1 character, see if it's a number (digit)
if(isNumeric(s)) {
// parseFloat wil read as many characters as it can, and drop the rest
temp = parseFloat(string.substr(i));
// okay, now skip the length of the float
i = i + temp.toString().length ;
result.push(temp);
}
}
return result;
}
window.onload = function() {
var numbers = numbersInString(mystring);
document.getElementById('log').innerHTML += numbers.join(',');
}
</script>
<div id="log"></div>

JavaScript Search and Loop - doesn't return correct values

Please, can you check my code where is the error? It should loop trough 1 array to choose each string and then loop through second array and check, if the value from second string contains value of first string.
for (var i = 0; i < oldLines.length; i++){
var subStringEach = oldLines[i];
var subStringEachNoDash = subStringEach.replace(/[^a-z0-9]/g,'');
// read New URLs and line by line save them as an object
var newLines = $('#newUrl').val().split(/\n/);
var newUrlResult = [];
for (var j = 0; j < newLines.length; j++){
var newUrlString = newLines[j];
var newUrlStringNoDash = newUrlString.replace(/[^a-z0-9]/g,'');
var isThere = newUrlStringNoDash.search(subStringEachNoDash);
if (isThere !== -1 ) {
newUrlResult[i] = newLines[j];
}
else {
newUrlResult[i] = "";
}
}
stockData.push({OldURL:oldLines[i],SearchSubstring:subStringEach,NewURL:newUrlResult[i]});
}
Now it finds only part of the results.. I place to first array:
anica-apartment
casa-calamari-real
ostrovni-apartman
and to the second array:
http://tempweb3.datastack.cz/be-property/anica-apartment/
http://tempweb3.datastack.cz/be-property/ostrovni-apartman/
http://tempweb3.datastack.cz/be-property/st-michael-apartment/
http://tempweb3.datastack.cz/be-property/casa-calamari-real/
and it will only find and return casa-calamari-real, http://tempweb3.datastack.cz/be-property/casa-calamari-real/ and the others returns empty..
Any ideas please?
Here is the full code on Codepen: https://codepen.io/vlastapolach/pen/VWRRXX
Once you find a match you should exit the inner loop, otherwise the next iteration of that loop will clear again what you had matched.
Secondly, you should use push instead of accessing an index, as you don't know how many results you will have. And as a consequence you will need to relate the find string with it (because i will not be necessary the same in both arrays)
So replace:
if (isThere !== -1 ) {
newUrlResult[i] = newLines[j];
}
else {
newUrlResult[i] = "";
}
with this:
if (isThere !== -1 ) {
newUrlResult.push({
searchSubstring: subStringEach,
newURL: newUrlString
});
break; // exit loop
}
At the end, just output newUrlResult.
NB: If you want to leave the possibility that a search string matches with more than one URL, then you don't need the break. The push will then still prevent you from overwriting a previous result.
I see that you solved already) But maybe you will like this code too)
newUrlResult variable could be a string I guess, because loop breaks when one value is found. If no values where found there will be just empty string. And I'm not sure you need to call newLines = $('#newUrl').val().split(/\n/) on every iteration.
var stockData = [];
oldLines.map(function(oldLine){
var cleanOldLine = oldLine.replace(/[^a-z0-9]/g,''),
newLines = $('#newUrl').val().split(/\n/),
newUrlResult = '';
for (var j = 0; j < newLines.length; j++){
var newLine = newLines[j],
cleanNewLine = newLine.replace(/[^a-z0-9]/g,''),
ifExists = cleanNewLine.search(cleanOldLine);
if (ifExists !== -1) {
newUrlResult = newLine;
break;
}
}
stockData.push({OldURL:oldLine, SearchSubstring:cleanOldLine, NewURL:newUrlResult});
});

How to remove all characters before specific character in array data

I have a comma-separated string being pulled into my application from a web service, which lists a user's roles. What I need to do with this string is turn it into an array, so I can then process it for my end result. I've successfully converted the string to an array with jQuery, which is goal #1. Goal #2, which I don't know how to do, is take the newly created array, and remove all characters before any array item that contains '/', including '/'.
I created a simple work-in-progress JSFiddle: https://jsfiddle.net/2Lfo4966/
The string I receive is the following:
ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC
ABCD/ in the string above can change, and may be XYZ, MNO, etc.
To convert to an array, I've done the following:
var importUserRole = 'ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC';
var currentUserRole = importUserRole.split(',');
Using console.log, I get the following result:
["ABCD", "ABCD/Admin", "ABCD/DataManagement", "ABCD/XYZTeam", "ABCD/DriverUsers", "ABCD/RISC"]
I'm now at the point where I need the code to look at each index of array, and if / exists, remove all characters before / including /.
I've searched for a solution, but the JS solutions I've found are for removing characters after a particular character, and are not quite what I need to get this done.
You can use a single for loop to go through the array, then split() the values by / and retrieve the last value of that resulting array using pop(). Try this:
for (var i = 0; i < currentUserRole.length; i++) {
var data = currentUserRole[i].split('/');
currentUserRole[i] = data.pop();
}
Example fiddle
The benefit of using pop() over an explicit index, eg [1], is that this code won't break if there are no or multiple slashes within the string.
You could go one step further and make this more succinct by using map():
var importUserRole = 'ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC';
var currentUserRole = importUserRole.split(',').map(function(user) {
return user.split('/').pop();
});
console.log(currentUserRole);
You can loop through the array and perform this string replace:
currentUserRole.forEach(function (role) {
role = role.replace(/(.*\/)/g, '');
});
$(document).ready(function(){
var A=['ABCD','ABCD/Admin','ABCD/DataManagement','ABCD/XYZTeam','ABCD/DriverUsers','ABCD/RISC'];
$.each(A,function(i,v){
if(v.indexOf('/')){
var e=v.split('/');
A[i]=e[e.length-1];
}
})
console.log(A);
});
You could replace the unwanted parts.
var array = ["ABCD", "ABCD/Admin", "ABCD/DataManagement", "ABCD/XYZTeam", "ABCD/DriverUsers", "ABCD/RISC"];
array = array.map(function (a) {
return a.replace(/^.*\//, '');
});
console.log(array);
var importUserRole = 'ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC';
var currentUserRole = importUserRole.split(',');
for(i=0;i<currentUserRole.length;i++ ){
result = currentUserRole[i].split('/');
if(result[1]){
console.log(result[1]+'-'+i);
}
else{
console.log(result[0]+'-'+i);
}
}
In console, you will get required result and array index
I would do like this;
var iur = 'ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC',
arr = iur.split(",").map(s => s.split("/").pop());
console.log(arr);
You can use the split method as you all ready know string split method and then use the pop method that will remove the last index of the array and return the value remove pop method
var importUserRole = ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC';
var currentUserRole = importUserRole.split(',');
for(var x = 0; x < currentUserRole.length; x++;){
var data = currentUserRole[x].split('/');
currentUserRole[x] = data.pop();
}
Here is a long way
You can iterate the array as you have done then check if includes the caracter '/' you will take the indexOf and substact the string after the '/'
substring method in javaScript
var importUserRole = 'ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC';
var currentUserRole = importUserRole.split(',');
for(var x = 0; x < currentUserRole.length; x++){
if(currentUserRole[x].includes('/')){
var lastIndex = currentUserRole[x].indexOf('/');
currentUserRole[x] = currentUserRole[x].substr(lastIndex+1);
}
}

Loop, get unique values and update

I am doing the below to get certain nodes from a treeview followed by getting text from those nodes, filtering text to remove unique and then appending custom image to the duplicate nodes.
For this I am having to loop 4 times. Is there is a simpler way of doing this? I am worried about it's performance for large amount of data.
//Append duplicate item nodes with custom icon
function addRemoveForDuplicateItems() {
var treeView = $('#MyTree').data('t-TreeView li.t-item');
var myNodes = $("span.my-node", treeView);
var myNames = [];
$(myNodes).each(function () {
myNames.push($(this).text());
});
var duplicateItems = getDuplicateItems(myNames);
$(myNodes).each(function () {
if (duplicateItems.indexOf($(this).text()) > -1) {
$(this).parent().append(("<span class='remove'></span>"));
}
});
}
//Get all duplicate items removing unique ones
//Input [1,2,3,3,2,2,4,5,6,7,7,7,7] output [2,3,3,2,2,7,7,7,7]
function getDuplicateItems(myNames) {
var duplicateItems = [], itemOccurance = {};
for (var i = 0; i < myNames.length; i++) {
var dept = myNames[i];
itemOccurance[dept] = itemOccurance[dept] >= 1 ? itemOccurance[dept] + 1 : 1;
}
for (var item in itemOccurance) {
if (itemOccurance[item] > 1)
duplicateItems.push(item);
}
return duplicateItems;
}
If I understand correctly, the whole point here is simply to mark duplicates, right? You ought to be able to do this in two simpler passes:
var seen = {};
var SEEN_ONCE = 1;
var SEEN_DUPE = 2;
// First pass, build object
myNodes.each(function () {
var name = $(this).text();
var seen = seen[name];
seen[name] = seen ? SEEN_DUPE : SEEN_ONCE;
});
// Second pass, append node
myNodes.each(function () {
var name = $(this).text();
if (seen[name] === SEEN_DUPE) {
$(this).parent().append("<span class='remove'></span>");
}
});
If you're actually concerned about performance, note that iterating over DOM elements is much more of a performance concern than iterating over an in-memory array. The $(myNodes).each(...) calls are likely significantly more expensive than iteration over a comparable array of the same length. You can gain some efficiencies from this, by running the second pass over an array and only accessing DOM nodes as necessary:
var names = [];
var seen = {};
var SEEN_ONCE = 1;
var SEEN_DUPE = 2;
// First pass, build object
myNodes.each(function () {
var name = $(this).text();
var seen = seen[name];
names.push(name);
seen[name] = seen ? SEEN_DUPE : SEEN_ONCE;
});
// Second pass, append node only for dupes
names.forEach(function(name, index) {
if (seen[name] === SEEN_DUPE) {
myNodes.eq(index).parent()
.append("<span class='remove'></span>");
}
});
The approach of this code is to go through the list, using the property name to indicate whether the value is in the array. After execution, itemOccurance will have a list of all the names, no duplicates.
var i, dept, itemOccurance = {};
for (i = 0; i < myNames.length; i++) {
dept = myNames[i];
if (typeof itemOccurance[dept] == undefined) {
itemOccurance[dept] = true;
}
}
If you must keep getDuplicateItems() as a separate, generic function, then the first loop (from myNodes to myNames) and last loop (iterate myNodes again to add the span) would be unavoidable. But I am curious. According to your code, duplicateItems can just be a set! This would help simplify the 2 loops inside getDuplicateItems(). #user2182349's answer just needs one modification: add a return, e.g. return Object.keys(itemOccurance).
If you're only concerned with ascertaining duplication and not particularly concerned about the exact number of occurrences then you could consider refactoring your getDuplicateItems() function like so:
function getDuplicateItems(myNames) {
var duplicateItems = [], clonedArray = myNames.concat(), i, dept;
for(i=0;i<clonedArray.length;i+=1){
dept = clonedArray[i];
if(clonedArray.indexOf(dept) !== clonedArray.lastIndexOf(dept)){
if(duplicateItems.indexOf(dept) === -1){
duplicateItems.push(dept);
}
/* Remove duplicate found by lastIndexOf, since we've already established that it's a duplicate */
clonedArray.splice(clonedArray.lastIndexOf(dept), 1);
}
}
return duplicateItems;
}

How Do I Parse a Pipe-Delimited String into Key-Value Pairs in Javascript

I want to parse the following sort of string into key-value pairs in a Javascript object:
var stringVar = 'PLNC||0|EOR|<br>SUBD|Pines|1|EOR|<br>CITY|Fort Myers|1|EOR|<br>';
Each word of 4 capital letters (PLNC, SUBD, and CITY) is to be a key, while the word(s) in the immediately following pipe are to be the value (the first one, for PLNC, would be undefined, the one for SUBD would be 'Pines', the one for CITY would be 'Fort Myers').
Note that '|EOR|' immediately precedes every key-value pair.
What is the best way of doing this?
I just realised it's technically a csv format with interesting line endings. There are limitations to this in that your variable values cannot contain any | or < br> since they are the tokens which define the structure of the string. You could of course escape them.
var stringVar = 'PLNC||0|EOR|<br>SUBD|Pines|1|EOR|<br>CITY|Fort Myers|1|EOR|<br>';
function decodeString(str, variable_sep, line_endings)
{
var result = [];
var lines = str.split(line_endings);
for (var i=0; i<lines.length; i++) {
var line = lines[i];
var variables = line.split(variable_sep);
if (variables.length > 1) {
result[variables[0]] = variables[1];
}
}
return result;
}
var result = decodeString(stringVar, "|", "<br>");
console.log(result);
If you have underscore (and if you don't, then just try this out by opening up your console on their webpage, because they've got underscore included :)
then play around with it a bit. Here's a start for your journey:
_.compact(stringVar.split(/<br>|EOR|\|/))
Try
function parse(str) {
var str = str.replace(/<br>/gi);
console.log(str);
var arr = str.split('|');
var obj = {};
for (var i=0; i<arr.length; i=i+4) {
var key = arr[i] || '';
var val_1 = arr[i+1] || '';
var val_2 = arr[i+2] || '';
if(key) {
obj[key] = val_1 + ':' + val_2; //or similar
}
}
return obj;
}
DEMO
This will work on the particular data string in the question.
It will also work on other data string of the same general format, but relies on :
<br> being discardable before parsing
every record being a group of 4 string elements delineated by | (pipe)
first element of each record is the key
second and third elements combine to form the value
fourth element is discardable.

Categories

Resources