Creating and implementing an array from space delimited text: AngularJS - javascript

and thank you for your patience. I am an experienced coder using old school methods, and have used the old style of Javascript for many years. I've known about JQuery, and such as that for a while, but have been "too busy" to learn the new things. Well, I am now working on learning those things, and have chosen AngularJS.
I am watching the tutorial videos, and reading the documents and API reference for AngularJS, but the different nomenclature does impede my progress. But I'm trying. For me, using an example of a "real" sort of problem helps me to understand how to leverage the functionality.
In this example, I have an array of Power Ball numbers, and want to be able to paste in the space delimited winning numbers you might copy off of the Power Ball site. This would then parse the input and hi-lite all of the individual numbers. Eventually, perhaps hi-liting any winning combinations in different ways. No, this isn't a product I'm building, but I thought this would cause me to use many different tools in this tool box.
So my questions are:
I initialized the array in my service (factory) and have shown that I can push to it from my controller. Is this correct?
Is my current way of doing things (e.g. ng-class usage, etc.) at least feasible, if not correct?
How could I use space delimited input in the input/text box to do the comparison for the style changes?
Here is an example of my JavaScript code. (note: I'm only pasting in one set of numbers for the array.)
var lotteryCheckApp = angular.module('lotteryCheckApp', []);
lotteryCheckApp.factory('PowerBall', function() {
var PowerBall = {};
PowerBall.numArray = ["42"];
PowerBall.myNumbers = [
{
First_Number: '03',
Second_Number: '07',
Third_Number: '17',
Fourth_Number: '21',
Fifth_Number: '42',
PowerBall: '21'
}
];
return PowerBall;
});
lotteryCheckApp.controller('PowerBallNumbersCtrl',function($scope,PowerBall) {
$scope.powerball = PowerBall;
$scope.winningStyle = true;
$scope.powerball.numArray.push("21");
$scope.myCheck = function(searchNum,numVal) {
// the following code works for a simple input to value check
if(searchNum == numVal) return true;
else return false;
}
I have a JSFiddle link: http://jsfiddle.net/Divermarv/VpyxZ/1/
Again, thank you all for your patience and responses.

Glad to hear you're getting into angular. Here is how I would solve your problem JSFiddle
I use ng-change to watch the input values,
<input type="text" ng-model="input" ng-change="convert()">
and feed that to a method that converts the input to an array of values.
$scope.convert = function() {
$scope.hiLite = $scope.input.split(" ");
}
Then your check function checks to see if the value is in the array
$scope.myCheck = function(searchNum,numVal) {
if(searchNum.indexOf(numVal) !== -1) return true;
else return false;
}
Is that kind of what you were thinking?

Related

Javascript - Randomly choosing items within an object, but not choosing excluded items

I am working on a project where I need to contain a lot of functions within an object so that I can access them with variables that combine in different ways to access different ones. I haven't written this in my main project yet, just tested it as a method and I'll put that test code below to hopefully better explain what I'm talking about. There will be a lot of functions in this object, and the aim is to have one of them randomly run when a button is pressed.
A key part of what I'm trying to make is that the user can exclude whichever functions they want from being randomly selected, and this is what is causing me some problems. I read through a lot of solutions for other problems, but all of them are just a little off (or at least I don't know how to apply them to this just yet). The first thing I tried was using an array and, depending on what option the user ticks, excluding or adding items to it and then randomly selecting from within that to get the random number, but I'm worried that an array of around 300 items would just slow things down or cause more problems than is really useful so I stepped away from this. I looked up how I could exclude numbers from the random generation too, but this tended to use for loops and only worked for a few numbers being excluded - after that I imagine that would cause problems too. I looked into excluding ranges of numbers from random generation as well, but the items that users exclude aren't guaranteed to be next to each other in the object, so that causes problems.
The plan in my head was to add a number at the end of the object key; the random number generator would choose from all non-excluded numbers (exclusion based on other parts of the key, such as excluding all 'salad' options in the test below), and then that number, along with the two or three other variables that make up the key bring us to an actual thing. So, in the theme of the below, "bacon" + "burger" + "lettuce" + "17" might be chosen based on the options the user chooses and the random number respectively and might lead to the 17th baconburgerlettuce based alert - I'm not making some kind of food shouting app, by the way, this really is just a demo...
This is... Hopefully less complicated than it sounds. I imagine I have explained it awfully, so if I can even just clarify something please let me know. Alternatively, if nesting functions inside an object for this purpose is straight up dumb, tell me! I want to learn the best way of doing things, rather than fumble through something ugly and inelegant!
var food;
var type;
var func = {
cheeseburger: function() {alert("This is CHEESE BURGER");},
baconburger: function() {alert("BACON BURGER reigns supreme!");},
cheesesalad: function() {alert("CHEESE SALAD hahahaha");},
baconsalad: function() {alert("BACON SALAD! That's right!");}
};
$(".cheese").click(function() {
food = "cheese";
$(".test").html(food);
});
$(".bacon").click(function() {
food = "bacon";
$(".test").html(food);
});
$(".burger").click(function() {
type = "burger";
$(".test2").html(type);
});
$(".salad").click(function() {
type = "salad";
$(".test2").html(type);
});
$(".go").click(function() {
func [food + type]();
});
const funcs = [
v => alert(v),
v => console.log(v),
v => alert( v + 1)
];
const excluded = new Set();
//to exclude a function
excluded.add(2);
function random(...args){
do {
var i = Math.floor( Math.random() * funcs.length );
} while( excluded.has( i ) );
funcs[i](...args);
}
//test it
random("test");
First of all you need some property to enable or disable functions.
var func = {
cheeseburger: {f: function() {...}, enabled: true},
baconburger: {f: function() {...}, enabled: true},
cheesesalad: {f: function() {...}, enabled: true},
baconsalad: {f: function() {...}, enabled: true},
...
};
Then a function to pick random one ignoring disabled ones.
Here arises first problem: If you just randomly pick one until you find one
which is not disabled, as the amount of disabled ones grows, the it will take
longer to find enabled one.
The easier solution is to use a cache like:
var cache;
function updateCache(){ // Using function we can update it when needed.
cache = Object.keys(func).filter(k=>func[k].enabled);
};
updateCache();
Then you need enable / disable methods too:
function enable(fn) {
func[fn].enabled = true;
updateCache();
};
function disable(fn) {
func[fn].enabled = false;
updateCache();
};
And, finally you just need to pick function keys from the cache:
function callRandomFn(){
var k = Math.floor(Math.random() * cache.length);
return fn[cache[k]]();
};

AngularJS soltuion to determining if any element in array1 exists in array2

I am working on an angularJS widget (my first) and I currently am looking for an angularJS solution to my problem.
Basically I have one array containing a list of string values.
var array1 = [
"Need to Know",
"Test Category 2",
"News"
];
and another array containing another list of string values
var array2 = [
"need to know",
"release notes",
"NEWS"
];
I need a true statement if any element from one array matches any element from the other array. The result also needs to be case insensitive.
Here is my current solution and works great.
angular.module("myWidget", function(...){
// angular code here
})
.service('arrayService', function() {
function arrayToLowerCase(array) {
return array.join("~!~").toLowerCase().split("~!~");
}
function arrayElementIsInArray(array1, array2) {
for (var i in array1) {
if (array2.indexOf(array1[i]) >= 0) {
return true;
}
}
return false;
}
function arrayCompare(array1, array2) {
return arrayElementIsInArray(arrayToLowerCase(array1), arrayToLowerCase(array2));
}
return {
arrayToLowerCase: arrayToLowerCase,
arrayElementIsInArray: arrayElementIsInArray,
arrayCompare: arrayCompare
};
})
the problem is my javascript coders (I primary work in c#) feel there is a more angularJS way to do this but they have brought nothing to the table as a definitive solution. It was suggested that the $filter module might be useful but I didn't see how it would exactly solve my problem.
If I already have the best solution, then awesome. If not please let me know what you think and lets go from there.
Thanks in advance.
EDIT: In response to some of the answers, I felt that I might have misinterpreted my request. What I am asking is there a built in function that angular provides that does this out of the box?
After researching this a bit more; the $filter Module will probably do it with a custom comparater implemented but that seems like way overkill for what I am looking for.
The current responses are all good stuff though. Thanks again!
Absolutely nothing to do with Angular. This is plain data structures and data manipulation. To say there should be a more AngularJS way of doing it would be like saying there should be a more MVC way to add two numbers.
Angular provides no basic data structures and utility set of functions beyond what is available in your browser's native list of array functions, which is different depending on which ECMAScript standard the browser supports.
You may want to look into a library like Lo-Dash for stuff like this (which you can use right along with Angular with no problems) as it's preferable to have proven code for these kind of data manipulations than to constantly have to debug your own.
With Lo-Dash, and remembering the requirement for case-insensitivity:
var array1Lowered = _.map(array1, function (value) { return value.toLowerCase(); });
var anyMatchesBool = _.any(array2, function (value) {
return _.contains(array1Lowered, value);
});
Note that I'm making the assumption that there will be no non-string items in either array.
Lo-Dash normalizes the API so you don't need to worry about what functions each browswer supports. If there's a native function, Lo-Dash will use it because it's faster. If not, Lo-Dash provides an all-JavaScript implementation.
Try this on for size. To me this really has nothing to do with Angular
(function(array1, array2) {
var tlc = function(a) { return a.toLowerCase(); };
array2 = array2.map(tlc);
array1 = array1.map(tlc);
return array1.filter(function(n) {
return array2.indexOf(n) != -1;
}).length > 0;
})(array1, array2);
Using native functions...
var intersection = array1.filter(function(n) {
return array2.indexOf(n) != -1
});
With help from Simplest code for array intersection in javascript

Filter html table containing large data (More than 12K row)

I m working on small project that contains list of Website(Max added 12000 name),
I m asking user to select their interested for that i created piece of code like on js fiddle: fiddle
$(document).ready(function () {
$("#title").keyup(function () {
if ($(this).val() != "") {
$("#doc_list_content tbody>tr").hide();
$("#doc_list_content td:contains-ci('" + $(this).val() + "')").parent("tr").show();
} else {
$("#doc_list_content tbody>tr").show();
}
});
});
$.extend($.expr[":"], {
"contains-ci": function (elem, i, match, array) {
return (elem.textContent || elem.innerText || $(elem).text() || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
}
});
Code is working fine with small amount of data, but when it is for 12000 row it cause browser not responding error.
I tried searching and played lot with my code. i want same type of functionality (on js fiddle) with js or php(littlebit knowledge of it)
My questions are:
1> Is it feasible to use this type of sorting?
2> any js/jquery solution?
3> I m aware of little bit of php as server side scripting, can it help to solve issue.
Thanks.
1 don't use jquery for that... it's slow. use pure javascript
2 create an array containing the table
var tbl=[
[a1,b1,c1,d1],
[a2,b2,c2,d2],
]
3 use the while-- loop as it's the fastest
var l=tbl.length
while(l--){
}
4 use very minimal shorthand or bitwise checks as they are faster.
var l=tbl.length
while(l--){
!tbl[l][0]||(SOMETOGGLEFUNCTION(l))//l is the index of the real table
}
this is the only way i know to check fast 12k records.
if it were me I would basically use some sort of 'paging' to limit the users 'view' of the data to smaller chunks of data, but perhaps still allow for some sort of 'search' feature that searches / filters through ALL the data (not just the visible chunk) - through an array I guess.
in a past project I found that for speed / performance it was best to incrementally add objects to the DOM when the user had first scrolled down to the 'bottom' of the current chunk of data, then I would add a new chunk and remove the previous chunk... sort of how a user turns pages of a book depending on where they are in the book as opposed to laying all the individual pages of a book out in front of them on the floor -- maybe not the best analogy but hopefully you follow my thinking. good luck.

Idiomatic way to select one element of array, with probability depending on a field of the element

Let's say I have this array:
[{name: "A", works: true}, {name: "B", works: true}, {name: "C", works: false}]
I want a function to select one element of this array, with, let's say 80% probability of getting a working element (works: true).
How could I do this elegantly? Would appreciate pseudo-code or code in any language.
(I can use underscore.js if needed, if using js)
In your situation first you are willing to toss a coin to decide if you are going to pick a working element or less. This can be done in JS with Math.random() which returns a value in [0,1].
value = Math.random() <= 0.8
will set value to true 80% of the times. At this point you already know which kind of element you want so you can just pick a random one and check if works or not. If it's of the correct type return it, otherwise pick another random one.
If your list is pretty long this may require many picks, in this case you could split the list and keep two lists (working ones and not workings ones).
The Function:
function chooser(an_array) {
var node_found = false;
var works = Math.random() <= .80;
while(node_found === false) {
var node = an_array[Math.floor(Math.random()*an_array.length)];
if(node.works === works) node_found = true;
}
return node;
}
Edit: Decided I should test it. Runs through the above function 10,000 times, results are good: http://jsfiddle.net/YyZfA/4/

Javascript: Get arrays based on dropdown selection

ok. I have a dropdown. well call it dropdownA. I have several arrays already fashioned, that i want to loop through, and put each individual value out onto the page into it's own input field, based on the selection in the dropdown. I know how to put together the loop to get the values out onto the page. anyway, here is the meta code.
meta1array=new Array('','','','','','');
meta2array=new Array('','','','','','');
meta3array=new Array('','','','','','');
function metacode(id){
{
var a=get.the.dd.selIndex;
var b=get.the.dd.options[a].value; //comes back as 'meta1'. other opts are meta2, meta3
var c=b+'array';
for(i=0;i<c.count;i++)
{
loop here to popout values
}
}
i have looked everywhere, and i haven't come up with anything. I also admit that my brain is starting to mushify from a few weeks straight of coding, and this is the first time i have come across this. so, please. i would be greatful for any help.
Global variables are members of the window object.
var c = window[b + 'array'];
It might be wise to make your arrays members of some other object though, for tighter scoping (avoid cluttering the global namespace).
metaobject = {
meta1array: ['','','','',''],
meta2array: ['','','','',''],
meta3array: ['','','','','']
};
// snip
var arr = metaobject[b + 'array'];
for(var i=0;i<arr.length;i++) {
//do work
}
Check out the fiddle using jquery here.

Categories