3

I'm trying to do a recursive search within an object and I'm trying to find all matches based on some criteria. I am using the following function:

function checkForTitleMatch(query, node) {
    var results = [];

    if (node.attr.title.indexOf(query) != -1) {
        results.push = node;
    }

    for (var i = 0; i < node.children.length; i++) {
        checkForTitleMatch(query, node.children[i]);
    }            

    return results;
}

I don't think that there's a problem in the matching and so on - I think that the problem is in the way I return the results within the recursion.

The result in my case is always an empty array, because the first/root element will never match(in my case) and the results of the child iterations are not correctly returned, imho.

Can someone please correct me or point out what has to be changed in order to get the correct results, please?

1
  • I was wondering I shouldn't do a push for the child recursions, if the result isn't an empty array, but there has to be a cleaner way :/ Commented May 26, 2014 at 6:48

2 Answers 2

3

You have two problems:

(1) results.push = node; It should be results.push(node).

(2) Each invocation of checkForTitleMatch creates its own results array, and the arrays never get aggregated.

One possible way to fix this:

function checkForTitleMatch(query, node) {
    var results = [];

    (function check(node) {
        if (node.attr.title.indexOf(query) != -1) {
            results.push(node);
        }

        for (var i = 0; i < node.children.length; i++) {
            check(node.children[i]);
        }
    })(node);           

    return results;
}

Even clear/faster would to use an attribute selector, e.g.

node.querySelectorAll('*[title*=' + query + ']');

Though this doesn't query the top-level node node, and assumes query does not have "special characters".

Sign up to request clarification or add additional context in comments.

1 Comment

Oh god did I really do push = node? :D Monday mornings.. Thanks a lot! I'll check it out!
0

Worth noting that you can solve this without a closure by using Array.concat to merge the results:

function checkForTitleMatch(query, node){
    var results = [];

    if (node.attr.title.indexOf(query) != -1){
        results.push(node);
    }

    for (var i=0; i<node.children.length; i++){
        results = Array.prototype.concat.apply(results, 
            checkForTitleMatch(query, node.children[i])
        );
    }            

    return results;
}

See also: Function.prototype.apply()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.