0

var foodwebsites = {
  "bacon": [{
    "url": "stackoverflow.com",
  }],
  "icecream": [{
    "url": "example.com",
  }],
  "cheese": [{
    "url": "example.com",
  }]
}

var baconfoodwebsites = foodwebsites.bacon.filter(function(elem) {
  return elem.url == 'example.com';
}).length;

var icecreamfoodwebsites = foodwebsites.icecream.filter(function(elem) {
  return elem.url == 'example.com';
}).length;

var cheesefoodwebsites = foodwebsites.cheese.filter(function(elem) {
  return elem.url == 'example.com';
}).length;

var allfoodwebsites = baconfoodwebsites + icecreamfoodwebsites + cheesefoodwebsites;

console.log(baconfoodwebsites, icecreamfoodwebsites, cheesefoodwebsites, allfoodwebsites)

I'd like to do the exact same thing without the repetion of all these individual nested objects (bacon, icecream and cheese).

I assume the answer would be like:

var allfoodwebsites = foodwebsites=.filter(function( elem) {
    return elem.url == 'example.com';
}).length;

Additional Info:

I'd like to use only jQuery + Pure Javascript if possible.

I'd like to find all nested objects with "url": "example.com"

3
  • There was no JSON here. You have POJOs - Plain Old JavaScript Objects Commented Apr 11, 2019 at 21:28
  • Don't use a filter for counting. You're creating an unnecessary array in memory. Commented Apr 11, 2019 at 21:30
  • Please clarify with the expected output, what you need to count? All available URLs? The number of URLs matching some pattern? Commented Apr 11, 2019 at 21:35

4 Answers 4

2

Using Object.values, Array#reduce() & Array#flat() . Note flat() may need polyfill in some environments

let foodwebsites = {"bacon": [{"url": "stackoverflow.com",}],"icecream": [{"url": "example.com",}],"cheese": [{"url": "example.com",}]};


const  getUrlCount = (url) => {
   return Object.values(foodwebsites)
       .flat()
       .reduce((a, {url:u})=> a + (url === u) , 0)

}

console.log(getUrlCount("example.com"))

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

2 Comments

++a ? why not just a + 1 ? Or even a + (url === u) ?
@JonasWilms never been conditioned to use booleans like that. Simple shortcut
2

The best option is the function reduce for counting approaches.

let foodwebsites = {"bacon": [{"url": "stackoverflow.com",}],"icecream": [{"url": "example.com",}],"cheese": [{"url": "example.com",}]};
let allfoodwebsites = Object.values(foodwebsites).
          reduce((a, array) => a + array.
            reduce((a, {url}) => a + (url === "example.com"), 0), 0);

console.log(allfoodwebsites);

Comments

1

Solution:

You can create a function that will iterate the object keys and search for a property and value inside each accessed key's array of child objects:

let amount = (p, v, i = 0) => 
(Object.keys(foodwebsites).forEach(k => foodwebsites[k].forEach(o => o[p] === v && i++))
, i);

and it can be used like this:

amount("url", "example.com"); // 2

Working Code Snippet:

var foodwebsites = {
  "bacon": [{
    "url": "stackoverflow.com",
  }],
  "icecream": [{
    "url": "example.com",
  }],
  "cheese": [{
    "url": "example.com",
  }]
}

    let amount = (p, v, i = 0) => 
    (Object.keys(foodwebsites).forEach(k => foodwebsites[k].forEach(o => o[p] === v && i++))
    , i);

console.log(
  amount("url", "example.com")
);
//2

2 Comments

So would it be let amount = amount("url", "example.com"); ?
@Tigerrrrr yes.
1

I'd actually built one array of all these nested entries:

  const sites = Object.values(foodwebsites).flat();

Then you can easily iterate over it and count all the keys:

 const count = (arr, key, value) => arr.reduce((acc, it) => acc + it[key] === value, 0);

 console.log(
   count(sites, "url", "example.com"),
   count(sites, "url", "stackoverflow.com")
 );

3 Comments

@mplungjan on mobile.
@mplungjan you are right with the typo, but surely I can
My bad . Missed that the second time

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.