Jump to content
iwato

Defining and Calling a Function within a Function

Recommended Posts

BACKGROUND:  I have created two functions of which the return value of one becomes the input value of the other.  This other then returns a value that is the desire goal of the two functional procedures.  So long as I run these functions separately, they produce the desired output.  When I attempt to combine them, however, I inevitably fail.  Please find below the successful procedure.  I will not bother you with my unsuccessful attempts.

INPUT ARRAY:

var searchItems = [{category:'Search Podcast',count:'1',target:'キャップチブ'},{category:'Search Newsletter',count:'3',target:'proposition'},{category:'Search Podcast',count:'0',target:'Grammar Captive'},{category:'Search Podcast',count:'1',target:'proposition'},{category:'Search Podcast',count:'1',target:'文法'},{category:'Search Newsletter',count:'1',target:'Grammar Captive'},{category:'Search Podcast',count:'2',target:'proposition'},{category:'Search Podcast',count:'0',target:'Grammar Captive'},{category:'Search Podcast',count:'1',target:'proposition'},{category:'Search Podcast',count:'1',target:'文法'}];

The selectAndList( ) Function

function selectAndList(propertyName, inputArr) {
    var propertyArr = [];
    inputArr.map(function(item) {
        propertyArr.push(item[propertyName]);							
    });
    return propertyArr;												
}

The countOccurrence( ) Function

function countOccurrence(inputArr) { 
    var occurrenceArr = [];
    var copy = inputArr.slice(0);
    for (var i = 0; i < inputArr.length; i++) {
        var myCount = 0;	
        for (var w = 0; w < copy.length; w++) {
            if (inputArr[i] == copy[w]) {
                myCount++;
                delete copy[w];
            }
        } 
        if (myCount > 0) {
            var a = new Object();
            a.value = inputArr[i];
            a.count = myCount;
            occurrenceArr.push(a);
        }
    } 
    return occurrenceArr;
};

Independent Calls Procedure:

var selectedPropertyArr = selectAndList('target', searchItems);
var occurrenceArr = countOccurrence(selectedPropertyArr);
console.log(occurrenceArr);

The result is an array with four objects each containing two properties (count and value) with their respective values.  Indeed, it is the desired outcome.

QUESTION:  How to I combine the above two functions into a single function called  countValueFrequency( ) with two arguments including  propertyName and inputArr?

OK.  The following works, but is this the most efficient way of achieving the desired result?

function countValueFrequency(propertyName, inputArr) {
    var propertyArr = [];
    inputArr.map(function(item) {
        propertyArr.push(item[propertyName]);							
    });
    function countOccurrence(inputArr) { 
        var occurrenceArr = [];
        var copy = inputArr.slice(0);
        for (var i = 0; i < inputArr.length; i++) {
            var myCount = 0;	
            for (var w = 0; w < copy.length; w++) {
                if (inputArr[i] == copy[w]) {
                    myCount++;
                    delete copy[w];
                }
            } 
            if (myCount > 0) {
                var a = new Object();
                a.value = inputArr[i];
                a.count = myCount;
                occurrenceArr.push(a);
            }
        } 
        return occurrenceArr;
    };
    return countOccurrence(propertyArr);
}
var newSelectedPropertyArr = countValueFrequency('target', searchItems);

Roddy

Edited by iwato

Share this post


Link to post
Share on other sites

Your given code was quite hard to follow, I assume this code is supposed to count the number of property occurences of a given property for an array of objects? 

const countOccurences=(property, arr)=>{
	let count=0
	arr.map(item=>{
		if(item.hasOwnProperty(property){
			count++
		}

	})
	return count

}

 

  • Like 1

Share this post


Link to post
Share on other sites

That function isn't recursive, so there's not really a reason to define a function inside another function and call it.  You can just put the code inside the one function.  Or, if you want to use the other function in other places, define it outside the function and just call it from inside.

  • Thanks 1

Share this post


Link to post
Share on other sites

~Code&Anime~:  I am not familiar with your syntax, and it is therefore difficult for me to comment on it, but it does appear to oversimplify the task.  Please correct me, if I am wrong.  

The countOccurrence() function receives as input an array that appears as something akin to the following:

Array [ "キャップチブ", "proposition", "Grammar Captive", "proposition", "文法", "Grammar Captive", "proposition", "Grammar Captive", "proposition", "文法" ]

The elements of this array are the values of a property called target found in each of the objects of the initial inputArr of the external function named countValueFrequency().  The countOccurrence() function counts the number of times that each of these values occurs in newly formed array and returns the result in the following format.

Array [ Object, Object, Object, Object ]

for which each object is of the following form:

count:  1
value: "キャップチブ"

count:  4
value: 'proposition'

etc.

Although somewhat awkward, these resulting objects must then be converted into arrays, so that they can be fed into the wordcloud2.js script for the creation of a word cloud.

Roddy

 

Share this post


Link to post
Share on other sites

JSG:  Actually there is still another function that is included in the countValueFrequency() function that converts the objects of the resulting array of the countOccurrence() function into arrays.  I just needed to know whether this is an acceptable procedure, and it appears that it is.

Thank you.

Roddy

Share this post


Link to post
Share on other sites

Well, it's not efficient to define a function inside another function that you're only going to use once, so if you're talking about efficiency then there's no reason to keep defining new functions every time you run that main function.  Just put the code right in the one function.

  • Thanks 1

Share this post


Link to post
Share on other sites
On 8/13/2018 at 2:39 PM, justsomeguy said:

Well, it's not efficient to define a function inside another function that you're only going to use once, so if you're talking about efficiency then there's no reason to keep defining new functions every time you run that main function.  Just put the code right in the one function.

This makes good sense.

Roddy

Share this post


Link to post
Share on other sites
On 8/13/2018 at 9:02 PM, iwato said:

~Code&Anime~:  I am not familiar with your syntax, and it is therefore difficult for me to comment on it, but it does appear to oversimplify the task.  Please correct me, if I am wrong.  

The countOccurrence() function receives as input an array that appears as something akin to the following:


Array [ "キャップチブ", "proposition", "Grammar Captive", "proposition", "文法", "Grammar Captive", "proposition", "Grammar Captive", "proposition", "文法" ]

The elements of this array are the values of a property called target found in each of the objects of the initial inputArr of the external function named countValueFrequency().  The countOccurrence() function counts the number of times that each of these values occurs in newly formed array and returns the result in the following format.


Array [ Object, Object, Object, Object ]

for which each object is of the following form:

count:  1
value: "キャップチブ"

count:  4
value: 'proposition'

etc.

Although somewhat awkward, these resulting objects must then be converted into arrays, so that they can be fed into the wordcloud2.js script for the creation of a word cloud.

Roddy

 

Yes but it seems that all the values for a given property are pudhed into an array, then the occurences are counted. This isn't very efficient. 

 

Edit: just realized i misunderstood the function. Will get back tomorrow.

Edited by ~Code&Anime~

Share this post


Link to post
Share on other sites
function selectAndList(propertyName, inputArr) {
    const propertyArr = [];
    inputArr.map(function(item) {
        propertyArr.push(item[propertyName]);							
    });
    return propertyArr;												
}
function countOccurences(propertyArr, value){
	const values =propertyArr.filter(function(prop){
		return prop==value
	})
	return values.length

}
function countOccurences(propertyArr){
	const map=new Map()
	propertyArr.map(function(val){
		if(map.has(val)){
			map.set(val, map.get(val)+1)
		}else{
			map.set(val, 0)
		}
		
	})
	return map

}

Apologies for this previous misunderstanding. I have rewritten my code in addition as to not use arrow functions as you mentioned you are not familiar with this. I thought it best to mention this as this may be useful when looking up info online. This is how such works for information, this was introduced in ES6:

 

function myFunc(val){

}

const myFunc = (val)=>{
}

You would call both with myFunc(val), this does not change.

also you should use const and let instead of var, var is defined globally, even when within a function. 

I have rewritten the function to reduce time complexity. There is no need to create multiple arrays. I have also defined a function to count occurences for a given property value

Edited by ~Code&Anime~

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×