最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Recursively loop through an array and return number of items? - Stack Overflow

programmeradmin3浏览0评论

I apologize if this has been asked before but I could not find an answer. How do I loop through an array with nested arrays and in the console print out the number of instances an item appears?

So console.log should print out the number 2 for the name "bob" because "bob" appears twice in the array.

Here is my array and what I have so far:

    var names = ["bob", ["steve", "michael", "bob", "chris"]];

    function loop(arr, item) {
      for (var i = 0; i < arr.length; i++) {
        if (arr[i] instanceof Array) {
          loop(arr[i], item);
        } else {
          if (arr[i] == item) {
            console.log(arr[i]);
          }
        }
      }
    }

    loop(names, "bob");

I apologize if this has been asked before but I could not find an answer. How do I loop through an array with nested arrays and in the console print out the number of instances an item appears?

So console.log should print out the number 2 for the name "bob" because "bob" appears twice in the array.

Here is my array and what I have so far:

    var names = ["bob", ["steve", "michael", "bob", "chris"]];

    function loop(arr, item) {
      for (var i = 0; i < arr.length; i++) {
        if (arr[i] instanceof Array) {
          loop(arr[i], item);
        } else {
          if (arr[i] == item) {
            console.log(arr[i]);
          }
        }
      }
    }

    loop(names, "bob");

Share Improve this question edited Mar 8, 2016 at 19:23 Rajaprabhu Aravindasamy 67.2k17 gold badges105 silver badges132 bronze badges asked Mar 8, 2016 at 18:01 stalwilstalwil 1251 gold badge1 silver badge11 bronze badges 3
  • 2 Your recursion looks about fine. Now you just have to count instances (and return that value), instead of console.logging them. Try it! – Bergi Commented Mar 8, 2016 at 18:03
  • Possible duplicate of How to flatten nested array in javascript? – jannis Commented Mar 8, 2016 at 18:11
  • Also answered here: stackoverflow.com/a/15030117/4494577 – jannis Commented Mar 8, 2016 at 18:15
Add a comment  | 

6 Answers 6

Reset to default 8

here you go, note that you can keep the counter value internally, to keep the rest of your code cleaner:

var names = ["bob", ["steve", "michael", "bob", "chris"]];

function loop(arr, item) {
  var result = 0;
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] instanceof Array) {
      result += loop(arr[i], item);
    } else {
      if (arr[i] == item) {
        result++;
      }
    }
  }
  return result;    
}


var result = loop(names, "bob");
console.log(result);

You need a counter

function loop(arr, item) {
    var count = 0;
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] instanceof Array) {
            count += loop(arr[i], item);
        } else {
            if (arr[i] == item) {
                count++;
                console.log(arr[i]);
            }
        }
    }
    return count;
}

var names = ["bob", ["steve", "michael", "bob", "chris"]],
    count = loop(names, "bob");

document.write(count);

You could also use reduce

var names = ['bob', ['steve', 'michael', 'bob', 'chris', ['bob']]];

function count(item, items) {
  return items.reduce(function(sum, x) {
    if (Array.isArray(x)) return sum + count(item, x);
    if (x === item) return sum + 1;
    return sum;
  }, 0);
}

count('bob', names); // => 3

Another option would be to use more generic functions and chain them together.

  1. flatten the input array; [1,[2,3,4,5,[6]]] => [1,2,3,4,5,6]
  2. filter the flattened array where each element matches your search element
  3. return the length of the filtered array

That would look something like this

flatten(names).filter(x => x === 'bob').length

I'll leave the implementation of flatten as an exercise for you

As of 2020, we have Array.prototype.flat method which makes this task trivial.

Here you go.

const names = ["bob", ["steve", "michael", "bob", "chris"]];
const nestedNames = ["bob", ["steve", ["michael", ["bob", ["chris"]]]]];

function countName(array, name, depth = Infinity) {
  return array.flat(depth).reduce((acc, cur) => acc + (cur === name ? 1 : 0), 0);
}

console.log(countName(names, 'bob')); // 2
console.log(countName(names, 'chris')); // 1

console.log(countName(nestedNames, 'bob')); // 2
console.log(countName(nestedNames, 'chris')); // 1

A pure form of recursion, No outside variable required.

Try to modify your logic like below,

var names = ["bob", ["steve", "michael", "bob", "chris",["bob"]]];
function loop(arr, item, cnt){
   cnt = cnt || 0;
   for(var i = 0; i < arr.length; i++){
     if(arr[i]==item){ cnt++; }
     else if(arr[i] instanceof Array) { return loop(arr[i], item, cnt); } 
   }
   return cnt;
}

loop(names,"bob"); //3

var names = ["bob", ["steve", "michael", "bob", "chris", ["bob"],["bob",["bob"]]], "bob"];

function find(arr, txt, cnt, match) {
  cnt = cnt || 0;
  match = match || 0;
  if (arr[cnt] === txt) { match++; } 
  else if (arr[cnt].push) { match = find(arr[cnt], txt, 0, match); } 
  if (++cnt === arr.length) { return match; }
  return find(arr, txt, cnt, match);
}

alert(find(names, "michael")); //6

const names = ["bob", ["steve", "michael", "bob", "chris"]];

function loop(arr, item) {
    let res = 0;

    for (let v of arr) {
        if (typeof v === 'object') res += loop(v, item);
        if (v === item) res++;
    }

    return res;    
}



const result = loop(names, "bob");
console.log(result);

发布评论

评论列表(0)

  1. 暂无评论