Filtering through a multidimensional array using u

2019-02-16 22:42发布

问题:

I have an array of event objects called events. Each event has markets, an array containing market objects. Inside here there is another array called outcomes, containing outcome objects.

I want to use Underscore.js or some other method to find all of the events which have markets which have outcomes which have a property named test.

I imagine this would be achieved using a series of filters but I didn't have much luck!

回答1:

I think you can do this using the Underscore.js filter and some (aka "any") methods:

// filter where condition is true
_.filter(events, function(evt) {

    // return true where condition is true for any market
    return _.any(evt.markets, function(mkt) {

        // return true where any outcome has a "test" property defined
        return _.any(mkt.outcomes, function(outc) {
            return outc.test !== undefined ;
        });
    });
});


回答2:

No need for Underscore, you could do this with native JS.

var events = [{markets:[{outcomes:[{test:x},...]},...]},...];
return events.filter(function(event) {
    return event.markets.some(function(market) {
        return market.outcomes.some(function(outcome) {
            return "test" in outcome;
        });
    });
});

Yet of course you could also use the corresponding underscore methods (filter/select and any/some).



回答3:

Try this:

_.filter(events, function(me) { 
    return me.event && 
        me.event.market && me.event.market.outcome && 
        'test' in me.event.market.outcome
}); 

DEMO



回答4:

var events = [
  {
    id: 'a',
    markets: [{
      outcomes: [{
        test: 'yo'
      }]
    }]
  },
  {
    id: 'b',
    markets: [{
      outcomes: [{
        untest: 'yo'
      }]
    }]
  },
  {
    id: 'c',
    markets: [{
      outcomes: [{
        notest: 'yo'
      }]
    }]
  },
  {
    id: 'd',
    markets: [{
      outcomes: [{
        test: 'yo'
      }]
    }]
  }
];

var matches = events.filter(function (event) {
  return event.markets.filter(function (market) {
    return market.outcomes.filter(function (outcome) {
      return outcome.hasOwnProperty('test');
    }).length;
  }).length;
});

matches.forEach(function (match) {
  document.writeln(match.id);
});

Here's how I would do it, without depending on a library:

var matches = events.filter(function (event) {
  return event.markets.filter(function (market) {
    return market.outcomes.filter(function (outcome) {
      return outcome.hasOwnProperty('test');
    }).length;
  }).length;
});