[Solved] Correctly build a filter function without DRY issue

That’s just these two features right?

As a result, for the next 5 to 10 years we’ll be compiling ES6 and ES7 code down to ES5, not using several coding techniques that we’ll tell ourselves are for compatibility reasons. We’ll fool ourselves into thinking that we’re writing really good code when the browsers will really be having to deal with the compiled ES5 code instead.

All because we fear breaking the web. Watch that “fear” word - it retards far too many things.

1 Like

No, compiling down to es5 is just pragmatic right now and it’s not difficult to do.

JS compilers like Babel could take on an approach like Autoprefixer where only the features that need fallbacks are compiled down, when browser support is solid then it stops being translated to something else.

Most of the time, It’s right to be concerned about breaking the web.

1 Like

One question that has arisen.

How do I capture the unique index of each object, even after sorting so the index doesn’t change?
As I’ll be linking to items using the value of index.

Something like:
curr.index - which says ‘undefined’

And is \n \t needed (which was added using Babel)?

function catFunction(json, name) {
  var list = json.filter(function (obj) {
    return obj.cat === name;
  }).reduce(function (prev, curr) {
    return prev + ('<li><a href="' + curr.index + '">\n      \t' + curr.title + '</a></li>');
  }, '');

  return '<h3>' + name + '</h3><ul>' + list + '</ul>';
}

Thanks, Barry

If you don’t want the index to change, you might add it as a property to each object when fetching the data, like

json.forEach((value, index) => {value.index = index});

This way the index could be an arbitrary URL as well.

Do you mean:

{
"index":0,
"id":"marker_0",
"title":"Title One",
"cat":"food"
},
{
"index":1,		
"id":"marker_1",
"title":"Title Two",
"cat":"food"
},
...

And how do we fit the forEach into our existing code?

I was also wondering, with the current code above, what loops through the json data? I mean, if we use forEach we know instantly what is happening, though above what is doing the iteration inside the function?

Main reason I ask is because I’ve been using each, forEach, Object.keys, etc and none of these are being used within the function. And would I be right in saying the functions just mentioned create an index automatically?

Cheers, Barry

You’d do this only once when retrieving the data. Of course, even better would be to have such a UID in the original data though.

Which function exactly are you referring to? By now there are quite a few in this thread… ^^

I’m currently using the function in my latest post #20… this was created after using some of the ES6 code from above and filtered through Babel.

I also realized today after some reading that the function I mention in #20 is what we call a Recursive Function if that is correct?

Is that is why we don’t have a forEach or each to iterate through the data - the function does the repetition?

You’d do this only once when retrieving the data. Of course, even better would be to have such a UID in the original data though.

So what do you suggest?

Add a unique index as I have done in #22 or rebuild the function using forEach?

Thanks, Barry

I have done what you suggested:

{
"uid": 0,
"id":"marker_0",
"title":"Title One",
"cat":"food"
},
{
"uid": 1,
"id":"marker_1",
"title":"Title Two",
"cat":"food"
},
...

Then changed

<a href="' + curr.uid + '">

You can see full update where I’m upto - http://jsfiddle.net/366hwksh/6/

Seems to do the trick :slight_smile:

What do you think?
And am I right of what I mention above about Recursive Function?

Cheers, Barry

No, this would be calling catFunction() from within itself… it would be possible to do it like that, although I think the iterative way is more efficient here, and most probably more readable.

And instead of forEach() we’ve been using filter() and reduce() here; these are other native methods to iterate over an array, but they also return a filtered array (such as by a certain category property) and a single value (such as an HTML string), respectively.

It really depends on the data and how you use it… if it’s coming from a database and should be persisted again, then it would make sense to store the IDs there. Now it just occurred to me that there’s an ID property in your OP fiddle anyway (ah, and in your above post as well)… so why not just use this one? ^^

And instead of forEach() we’ve been using filter() and reduce() here; these are other native methods to iterate over an array, but they also return a filtered array (such as by a certain category property) and a single value (such as an HTML string), respectively.

Ahhh moment… yes this makes a little more sense now m3g4p0p… filter and reduce, wasn’t to sure what they were exactly doing, thanks for the links.

this would be calling catFunction() from within itself

Recursion = When a function calls itself until it dosen’t (also as you mention above) read this today and thought the catFunction() was a Recursive Function.

So are you saying its not a Recursive Function because we’re using filter and reduce, otherwise it would be?

…so why not just use this one

Yes as shown in the latest fiddle example, this works good now.

I think in this instance now that it’s working, keep things how they are… as the saying goes “over engineer things

Lots information now which I’ll digest :sunglasses:

Well a recursive solution might look like e.g.

function getList(array, cat) {
  if (!array.length) return '';

  var obj = array.pop();
  var item = obj.cat === cat ? `<li>${obj.title}</li>` : '';

  // Call the function again on the popped sub-array, and
  // append the result to the current list item
  return item + getList(array, cat);
}

The return statement is where the recursion happens here. But again, this might not be terribly efficient for just iterating over an array; typically you’d use something like this when the data is nested itself.

The return statement is where the recursion happens here.

Yes this is what I realised today, thanks for confirming :slight_smile:

typically you’d use something like this when the data is nested itself

Meaning? Not in an array?
Sorry for silly question, though array and nested data are two different things?

I do understand what your saying and thanks for example. I just want to be clear on when and when not to use one over the other.

Barry

yes they are different - nested data is where recursion might make sense - recursion doesn’t make sense for an array.

Thanks for clearing that up.

So… this is an array.
But what does nested data look like, nested data where recursion would make more sense?

[{
"uid": 0,
"id":"marker_0",
"title":"Title One",
"cat":"food"
},
{
"uid": 1,
"id":"marker_1",
"title":"Title Two",
"cat":"food"
} ....]

Thanks, barry

Nested data doesn’t look at all like that array of objects you just posted. It is difficult to come up with a good example of nested data as it is very rare for data to actually be structured that way.

One of the books that I have that discusses recursion uses the example of a railway line where each station can communicate with those on either side and the station at one end of the line needs to find out how many passengers are waiting at each station. That involves passing the request from station to station down the line and back and so the data returned would then be nested. For example each station passes back an array containing their answer and the array they received from the next station - looking something like this:

[5, [6, [2,[7]]]]
1 Like

Sounds a little confusing :neutral_face:

Thanks for the detailed explanation, makes things a bit clearer felgall. I think I’ll try and avoid this until I get a good understanding of things.

Cheers, Barry

Nested data could be complex objects where some values are arrays of other objects etc., or actually something as simple as a multidimensional array. E.g. consider this array

var data = [
  'foo',
  'bar',
  [
    'baz',
    'boo'
  ],
  'bam',
  [
    'bee',
    'zoo',
    [
      'zap',
      'zang'
    ]
  ]
];

you might want to render as nested ul elements. You don’t know how deeply nested that array is though, so you can’t just use a certain number of nested for loops or something. Here you’d use recursion, like e.g.

var getList = function(array) {
  var list = '<ul>';
  var element;
  
  for (var i in array) {
    element = array[i];
    list += '<li>';
    
    if (Array.isArray(element)) {

      // If the element is itself another array,
      // recursively append it to the current
      // list item
      list += getList(element);
    } else {

      // Otherwise, just append the current element
      list += element;
    }
    
    list += '</li>';
  }
  
  return list + '</ul>';
}

fiddle

1 Like

This was my first impression when thinking of nested data, though I’d say this is a sort of random dataset - no continued structure.

Making a little more sense now with your example accompanied by felgalls information.

You make it look so easy ha :sunglasses:

Thanks!
Will bookmark these examples.

Barry

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.