【问题标题】:intersection of objects except for one attribute between two arrays除了两个数组之间的一个属性之外的对象的交集
【发布时间】:2019-12-18 15:35:44
【问题描述】:

我有两个数组,它们包含相同类型的对象(相同的属性但关联的值不同)。我想比较两个数组并匹配除一个属性外相等的对象。然后我想在第一个数组中找到匹配的对象的索引,以便将这些对象推送到不同的数组中。

我认为所有这些都可以使用 lodash 完成,并且我想避免 for 循环,以使其尽可能高效

请注意,我在一个 js 类中工作

这是我的尝试(不工作)

class MatchPlayers {
    constructor(){
        this.TeamA = [
            {weight:'75',height:'170', foot:'Left', available:true},
            {weight:'88',height:'190', foot:'Right', available:true},
            {weight:'65',height:'163', foot:'Right', available:false},
            {weight:'70',height:'168', foot:'Left', available:true}
        ]

        this.TeamB = [
            {weight:'75',height:'170', foot:'', available:true},
            {weight:'93',height:'201', foot:'', available:true},
            {weight:'65',height:'163', foot:'', available:false}
        ]

        this.MatchedPlayers = []
    }

    PlayersMatch (){
        for(this.i=0;this.i<this.TeamA.length;this.i++){
            if (_.intersection(this.TeamA,{weight:this.TeamB.weight, height:this.TeamB.height, available:this.TeamB.available})){
              this.position = _.findIndex(this.TeamA,{weight:this.TeamB.weight, height:this.TeamB.height, available:this.TeamB.available})
              this.MatchedPlayers.push(this.TeamA[this.position])
            } else {console.log('No matchable players')}
          }
        console.log(this.MatchedPlayers)
    }
}

在这种情况下,我想匹配除“脚”之外具有相同属性的对象,因此预期输出为:

//Expected Output:
this.MatchedPlayers = [
    {weight:'75',height:'170', foot:'Left', available:true}, 
    {weight:'65',height:'163', foot:'Right', available:false}
]

【问题讨论】:

  • 如果你想使用 lodash 交集,你可以使用_.intersectionBy_.intersectionWith。第二个可能更适合您的用例
  • 您必须为_.intersectionWith 编写一个自定义函数,该函数只比较您想要比较的属性,或者比较除您不想要的属性之外的所有属性。
  • 我试过了,但它不起作用。但是我也可以使用不同的功能

标签: javascript arrays lodash


【解决方案1】:

您可以采取一种简化的方法并省略foot 属性,并通过_.isEqual 获取左上方属性的交集。

var a = [{ weight: '75', height: '170', foot: 'Left', available: true }, { weight: '88', height: '190', foot: 'Right', available: true }, { weight: '65', height: '163', foot: 'Right', available: false }, { weight: '70', height: '168', foot: 'Left', available: true }],
    b = [{ weight: '75', height: '170', foot: '', available: true }, { weight: '93', height: '201', foot: '', available: true }, { weight: '65', height: '163', foot: '', available: false }],
    omitFoot = o => _.omit(o, 'foot'),
    intersection = _.intersectionWith(
        _.map(a, omitFoot),
        _.map(b, omitFoot),
        _.isEqual
    );

console.log(intersection);
.as-console-wrapper { max-height: 100% !important; top: 0; }
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"&gt;&lt;/script&gt;

【讨论】:

    【解决方案2】:

    要创建具有自定义行为的交集,请使用_.intersectionWith()。该方法接受一个在两个对象之间进行比较的谓词。在这种情况下,比较几乎与_.isEqual() 相同,但它应该忽略一个属性。

    您可以使用_.isEqualWith() 创建谓词,它接受自定义函数。如果比较键(第三个参数)是foot,它应该返回true(等于,因为我们不在乎),如果不是,它应该返回undefined,以便_.isEqualWith()可以进行标准_.isEqual()比较.

    const a = [{ weight: '75', height: '170', foot: 'Left', available: true }, { weight: '88', height: '190', foot: 'Right', available: true }, { weight: '65', height: '163', foot: 'Right', available: false }, { weight: '70', height: '168', foot: 'Left', available: true }];
    const b = [{ weight: '75', height: '170', foot: '', available: true }, { weight: '93', height: '201', foot: '', available: true }, { weight: '65', height: '163', foot: '', available: false }];
    
    const result = _.intersectionWith(a, b, 
      _.partialRight(_.isEqualWith,
        (...args) => args[2] === 'foot' ? true : undefined
      )
    );
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"&gt;&lt;/script&gt;

    【讨论】:

      猜你喜欢
      • 2017-08-06
      • 2016-12-23
      • 2017-01-04
      • 1970-01-01
      • 2017-09-03
      • 2020-11-04
      • 1970-01-01
      • 2016-01-20
      • 2013-05-30
      相关资源
      最近更新 更多