Using the following function, I am searching an array for the existence of a value;
var checkboxValues = ['large-car', 'small-car', 'automatic'];
var carType = ["large-car"];
function searchArray(arguments)
{
var o = {};
for(var i=0;i<arguments.length;i++)
{
o[arguments[i]]=null;
}
return o;
}
if (carType in searchArray(checkboxValues) )
//do something...
This condition works well when carType (which is an array itself) contains only one value but when carType contains multiple values such as,
var carType = ["large-car", "4WD"];
...then the function will return false.
To give some background, what I am trying to do is show or hide map markers (via Google Maps) based on certain conditions,
Automatic
Manual
Small Car
Large Car
4WD
Each of these values is represented as a checkbox. If "Automatic" and "Small Car" are selected, then only shown map markers who contain both those values.
If "Automatic", "Small Car" and "Large Car" are selected then only show values which match those selections.
This works if the carType array contains only a single value but as an individual vehicle may have more than one type as shown above, this is where the function fails.
What's the best way to write the function to allow for comparing multiple values in one array against that of another?
Snippet taken from this answer.
function arrayUnique(array) {
var a = array.concat();
for(var i=0; i<a.length; ++i) {
for(var j=i+1; j<a.length; ++j) {
if(a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
};
And then use it like this:
var checkboxValues = ['large-car', 'small-car', 'automatic'],
carType = ["large-car"],
merged = arrayUnique(checkboxValues.concat(carType));
if (merged.length === checkboxValues.length) {...}
If you need to return the matching elements of two arrays you can do this:
function matchArrays(base, toSearch) {
var returnArray = [];
for (var i = 0; i < toSearch.length; i++) {
if (base.indexOf(toSearch[i]) !== -1) returnArray.push(toSearch[i]);
}
return returnArray;
}
Usage:
var match = matchArrays(checkboxValues, carType); // return "large-car"
Take a look at array_intersect from PHPJS, a reproduction of PHP's array_intersect function in JavaScript.
You can use js functionality to match array.
One ways is to use indexOf() function that return the index of the string if it is found in array or -1 if not found.
var checkboxValues = ["large-car", "small-car", "automatic"];
var carType = ["large-car","automatic","some car"];
function searchMatch(carType) {
var result = new Array();
for(var i=0;i < carType.length;i++) {
// If match found push the match to the result array.
if(checkboxValues.indexOf(carType[i]) != -1){
result.push(carType[i])
}
}
return result ;
}
As a result you will get ["large-car","automatic"];
if you use underscoreJs may look like this
var checkboxValues = ['large-car', 'small-car', 'automatic'];
var carType = ['small-car','automatic'];
var result=_.any(checkboxValues,function(checkbox){
return _.any(carType,function(carT){ return carT==checkbox;});
});
Try this jQuery solution:
<script type="text/javascript">
var checkboxValues = ['large-car', 'small-car', 'automatic'];
var carType = ["large-car"];
if ($.inArray(carType[0].toString(), checkboxValues ) == -1) {
return false;// if not exists
}
</script>
Related
I am building a web application that is primarily using Tableau elements (filters, visualizations, etc.) and the problem I have run into is in passing a large amount (dynamic) of filtered parameters across web pages. I've been trying to work with the JavaScript below, but not having any luck.
function getFilterd()
{
var worksheets = vizFilter.getWorkbook().getActiveSheet().getWorksheets();
var prjArray = window.location.search.substring(1).split(',');
var newArray = [];
//Run through field/filter names
var displayFilters = function (filters) {
for (var i = 0; i < filters.length; i++) {
filterName = filters[i].getFieldName();
//If field/filter name == PRJECT then store selected values in an array
if (filterName == 'PRJECT') {
filterList = []
for (var z = 0; z < filters[i].getAppliedValues().length; z++) {
filterList[z] = filters[i].getAppliedValues()[z].value;
}
//Compare filterList values to prjArray and push to newArray if a match
for (var t = 0; t < filterList.length; t++) {
if (filterList[t].getAppliedValues()[t].value.substring(4) == prjArray) {
newArray.push(filterList[t]);
}
}
}
}
}
}
//Runs through each worksheet in active workbook (optional)
for (var worksheetIndex = 0; worksheetIndex < worksheets.length; worksheetIndex++){
worksheets[worksheetIndex].getFiltersAsync().then(displayFilters);
}
}
So I was finally able to figure this out. The logic below was incorrect as mentioned by Justin in his answer:
//Compare filterList values to prjArray and push to newArray if a match
for (var t = 0; t < filterList.length; t++) {
if (filterList[t].getAppliedValues()[t].value.substring(4) == prjArray) {
newArray.push(filterList[t]);
}
}
In addition, were some syntax errors in the if statement. The following is the revised statement that did return the desired array:
//Compare filterList values to prjArray and push to newArray if a match
newArray = []
for (var t = 0; t < filterList.length; t++){
if (prjArray.indexOf(filterList[t].substring(4)) != -1) {
newArray.push(filterList[t]);
};
}
When you do a split() on window.location.search.substring(1), you return an array. Here, you are comparing a substring against an array, and that is always going to return false.
if (filterList[t].getAppliedValues()[t].value.substring(4) == prjArray) {
newArray.push(filterList[t]);
}
Additionally, you are only putting values into filterList and trying to access them with getAppliedValues is not going to work.
You need to test if the substring is within the array. You can do this using includes() to determine if the array includes the value provided.
if (prjArray.includes(filterList[t].substring(4))) {
newArray.push(filterList[t]);
}
The includes() method is not completely supported by all browsers. If you need backward compatibility,you can do this using indexOf and test is it returns other than -1
if (prjArray.indexOf(filterList[t].substring(4)) !== -1) {
newArray.push(filterList[t]);
}
Here is my current filter function (quite incomplete)
$('input:checkbox.types').click(function(){
filterMarkers();
});
function filterMarkers() {
var checked = [];
$('input:checkbox.types:checked').each(function(){
checked.push($(this).val());
});
checked.sort();
var andor = '';
var andor = $('[name="and-or"]:checked').val();
if(andor == 1) {
// and
console.log(checked);
for (var i = 0; i < markers.length; i++) {
var types = markers[i]['types'].split(",");
types.sort();
console.log(types);
}
} else {
// or
}
}
Here is an image of what I have so far.
http://snag.gy/rKSTA.jpg
Let us say this for simplicity.
A = checked checkboxes
B = array with values of current item in map marker iteration / current iteration marker
I was able to get the values of the checked checkboxes. I was also able to convert the comma delimited string of each marker into an array. I would like to be able to check if B contains ANY of A (OR) and be able to check that B must contain A (AND).
Any ideas?
Here is the page in question for those wanting a 'feel' for what I am trying to accomplish. Thanks!
https://www.cablework.co/company
This page outputs what I have currently to console.
Once I can figure this out, I will then be able to hide/show markers based on the result.
Here's an example function. You would run test on every marker against the types array.
http://jsfiddle.net/q1k6e74d/5/
function test(op,types,marker){
var pass;
if(types.length === 0 || marker.length === 0){
return false;
}
if(op==="and"){
pass = true;
for(var i in types){
if( $.inArray(types[i],marker) == -1 ){
pass = false;
}
}
}else{ //or
pass = false;
for(var i in marker){
if( $.inArray(marker[i],types) !== -1 ){
pass = true;
}
}
}
return pass;
}
var a = [1,4];
var b = [1,5];
console.log("test a",a,"and b",b,test("and",a,b));
console.log("test a",a,"or b",b,test("or",a,b));
Could be shorter but it's easiest to understand this way I think.
I've created a function that will search for individual letters from a string regardless of case and order. Here is what it looks like.
function match(string, pattern) {
string = string.toLowerCase();
pattern = pattern.toLowerCase();
var patternarray = pattern.split("");
for (i = 0; i < pattern.length; i++) {
if (patternarray[i] >= "a" && patternarray[i] <= "z") {
if (string.indexOf(patternarray[i]) == -1) return false
}
}
return true
}
Now I want to do a similar thing except this time I will be searching an array, and instead of returning true/false I would like to return a new array containing the places in which the string pops up.
For example, if my variable contents were ["Oranges","Apples","Bananas"] and my search was "n", the function would return [0,2]. I am a beginner with JavaScript so thorough explanation would be helpful.
Thanks!
function matchArray(array, pattern) {
var i,
len = array.length,
result = [];
for (i = 0; i < len; ++i) {
if (match(array[i], pattern)) {
result.push(i);
}
}
return result;
}
Underscorejs has a function that should take care of this for you. Just take a look at the filter function. It has the ability to return a new array with items that passed a truth test.
var aArray = _.filter(['asdf','ddd','afsf'], function(item){
return (item.indexOf('a') !== -1);
}
My aim is to find out if we have at least two different values in an array. How to find out this using pure javascript. By now, I use this funcion, who tells me if there are repeated values in an array...
function verificar(array)
{
var filtrado_arr = array.sort();
var resultados = [];
for (var i = 0; i < array.length - 1; i++) {
if (filtrado_arr[i + 1] == filtrado_arr[i]) {
resultados.push(filtrado_arr[i]);
}
}
if (resultados.length > 0)
{
alert("Repeated results"+resultados+".Unable to send to graph.");
return false;
}
else
{
alert("No repeated measures, we can set graph");
return true;
}
}
But this is not enought, of course.
Using a sort and an extra array seems like an overly expensive way to perform this simple task. What is wrong with the following?
function verificar(arr)
{
for (var i=1; i<arr.length; i++) {
if (arr[i-1] != arr[i])
return true;
}
return false;
}
function verificar(array) {
for(i=1; i<array.length; i++){
if(array[0] !== array[i])
return true;
}
return false;
}
Your code implies that you want to check for duplicates, not verify that you have at leas one unique pair of values as stated in your question.
I'd just add another method to the pool of answers: checking for duplicates using Array.some():
function hasDuplicates(array){
return array.some( function( elm, idx ){
return array.lastIndexOf( elm ) > idx;
});
}
console.log( hasDuplicates([3,4,1,2]) ); // false
console.log( hasDuplicates([3,4,1,3,2]) ); // true
Just check the first value of the array "filitrado_arr[0]" against all of the other values in the array. If one of the values matches the first value of array, you know that there is a repeated value. Here is an example of how you could implement that logic:
function verificar(array){
var repeats = false
for (var i = 1; i < array.length; i++) {
if (array[0] == array[i]) {
repeats = true;
return repeats
}
}
}
However this answer matches the goal implied by the alerts in your original function not the goal in the question itself.
here is my javascript:
var json = '{"GetReportIdResult":[{"bulan":"4","total":"1728","type":"CHEESE1K","uang":"8796383"},{"bulan":"4","total":"572476","type":"ESL","uang":"5863408410"},{"bulan":"4","total":"33507","type":"WHP","uang":"235653242"},{"bulan":"5","total":"4761","type":"CHEESE1K","uang":"134877865"},{"bulan":"5","total":"245867","type":"UHT","uang":"1446787280"},{"bulan":"5","total":"47974","type":"WHP","uang":"631929807"},{"bulan":"6","total":"5762","type":"CHEESE1K","uang":"293393832"},{"bulan":"6","total":"236803","type":"UHT","uang":"2219506085"},{"bulan":"6","total":"24853","type":"WHP","uang":"386175022"}]}';
obj = JSON.parse(json);
var arrayobj = obj.GetReportIdResult.length;
alert (arrayobj);
I want to count how many type in the same bulan value, (e.g. there are 3 type = CHEESE1K, UHT, and ESL in bulan = 4)
how to do that?
There's still a typo in your JSON: you've got two commas in a row between the first two "bulan":"6" objects. But assuming you fix that...
If you're asking how to count distinct types for a particular bulan value you can do something like this:
function countTypesForBulan(resultArray, bulanVal) {
var i,
types,
count = 0;
for (i=0, types = {}; i < resultArray.length; i++)
if (resultArray[i].bulan === bulanVal && !types[resultArray[i].type]) {
types[resultArray[i].type] = true;
count++;
}
return count;
}
console.log( countTypesForBulan(obj.GetReportIdResult, "4") ); // logs 3
The above loops through the array looking for a particular bulan value, and when it finds one it checks if it has already seen the associated type - if not, it adds it to the types object and increments the counter.
Demo: http://jsfiddle.net/pAWrT/
First of all, put the JSON into a string,
else your example code wont work.
var json = '{"GetReportIdResult":[{"bulan":"4","total":"1728","type":"CHEESE1K","uang":"8796383"},{"bulan":"4","total":"572476","type":"ESL","uang":"5863408410"},{"bulan":"4","total":"33507","type":"WHP","uang":"235653242"},{"bulan":"5","total":"4761","type":"CHEESE1K","uang":"134877865"},{"bulan":"5","total":"245867","type":"UHT","uang":"1446787280"},{"bulan":"5","total":"47974","type":"WHP","uang":"631929807"},{"bulan":"6","total":"5762","type":"CHEESE1K","uang":"293393832"},,{"bulan":"6","total":"236803","type":"UHT","uang":"2219506085"},{"bulan":"6","total":"24853","type":"WHP","uang":"386175022"}]}';
Then,
Iterate with for and count in a variable or a hashmap.
Since GetReportIdResult is an array, you can:
for( var i : obj.GetReportIdResult ){
obj.GetReportIdResult[i] ... // Use at will.
This will give you a map object which will contain the count for each bulan value. For example, map['4'].count will return 3.
var i, row, arr = obj.GetReportIdResult, map = {};
for (i = 0; i < arr.length; i++) {
row = arr[i];
map[row.bulan] = map[row.bulan] || {count: 0};
if (map[row.bulan][row.type] === undefined) {
map[row.bulan][row.type] = row.type;
map[row.bulan]['count'] += 1;
}
}
console.log (JSON.stringify(map));
JSFiddle here.