【问题标题】:Remove object in Array of Objects if few key-value pair are same and another key-value are less than other object如果少数键值对相同​​且另一个键值小于其他对象,则删除对象数组中的对象
【发布时间】:2018-10-19 21:28:44
【问题描述】:

我有这种类型的对象

var array = [ 
 { "foo": 1, "bar": 2, "baz": 3 },
 { "foo": 1, "bar": 2, "baz": 5 },
 { "foo": 1, "bar": 2, "baz": 4 },
 { "foo": 2, "bar": 1, "baz": 3 },
 { "foo": 2, "bar": 1, "baz": 7 },
 { "foo": 1, "bar": 3, "baz": 4 } 
]

如果 'foo' 和 'bar' 键值相同,则选择键 'baz' 更大的值并删除其他对象。

喜欢这个

[ { "foo": 1, "bar": 2, "baz": 5 },
{ "foo": 2, "bar": 1, "baz": 7 },
{ "foo": 1, "bar": 3, "baz": 4 } ]

我试过这个solution,但它不适合我。 这个question 不像我的问题。

那么,下划线/lodash 库或仅在 javascript 中的解决方案是什么。

【问题讨论】:

标签: javascript underscore.js lodash


【解决方案1】:

使用 lodash,您可以按 foobaz 的值组合进行分组。然后映射结果,在每组中选择baz值最高的对象:

var array = [ 
 { "foo": 1, "bar": 2, "baz": 3 },
 { "foo": 1, "bar": 2, "baz": 5 },
 { "foo": 1, "bar": 2, "baz": 4 },
 { "foo": 2, "bar": 1, "baz": 3 },
 { "foo": 2, "bar": 1, "baz": 7 },
 { "foo": 1, "bar": 3, "baz": 4 } 
]

var result = _.map(
  _.groupBy(array, o => `${o.foo}-${o.bar}`),
  g => _.maxBy(g, 'baz')
)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

使用 vanilla JS,您可以将数组缩减为一个对象(累加器),对累加器键使用类似的约定(barbaz 的组合)。每当数组中的一个对象和存储在累加器中的一个对象具有相同的键时,将保留具有最高 baz 值的对象。

const array = [ 
 { "foo": 1, "bar": 2, "baz": 3 },
 { "foo": 1, "bar": 2, "baz": 5 },
 { "foo": 1, "bar": 2, "baz": 4 },
 { "foo": 2, "bar": 1, "baz": 3 },
 { "foo": 2, "bar": 1, "baz": 7 },
 { "foo": 1, "bar": 3, "baz": 4 } 
]

const result = Object.values(array.reduce((r, o) => {
  const key = `${o.foo}-${o.bar}`
  
  if(!r[key] || r[key].baz < o.baz) r[key] = o
  
  return r
}, {}))

console.log(result)

【讨论】:

    【解决方案2】:

    另一种可能性是按foobar 的升序和baz 的降序对数组进行排序,然后执行reduce

    var array = [ 
     { "foo": 1, "bar": 2, "baz": 3 },
     { "foo": 1, "bar": 2, "baz": 5 },
     { "foo": 1, "bar": 2, "baz": 4 },
     { "foo": 2, "bar": 1, "baz": 3 },
     { "foo": 2, "bar": 1, "baz": 7 },
     { "foo": 1, "bar": 3, "baz": 4 } 
    ];
    
    const res = array
      .sort((a, b) => a.foo - b.foo || a.bar - b.bar || b.baz - a.baz)
      .reduce((acc, curr) => {
        const prev = acc[acc.length - 1] || {};
        if (!(curr.foo === prev.foo && curr.bar === prev.bar)) acc.push(curr);
        return acc;
      }, []);
    
    console.log(res);

    【讨论】:

      【解决方案3】:

      我试过这个solution,它对我有用,

      这就是解决办法

      var result = ab.reduce((p,c) => {var o = p.find(e => e.foo === c.foo && e.bar === c.bar);
      !!o ? o.baz = (o.baz > c.baz ? o.baz : c.baz) : p.push(c);
      return p;},[]);
      

      但我不明白这段代码的流程。所以,我决定扩展代码并尝试理解代码

      所以,首先我阅读了reducefind 并扩展了代码

      var result = ab.reduce((newArray, singleObj) => {
        var sameKeyValueObj = newArray.find(obj => {
          return obj.foo === singleObj.foo && obj.bar === singleObj.bar
        });
        sameKeyValueObj ? sameKeyValueObj.baz = (
          sameKeyValueObj.baz > singleObj.baz ? sameKeyValueObj.baz : singleObj.baz
        ) : newArray.push(singleObj);
        return newArray;
      }, []);
      

      这对我来说是一个可以理解的解决方案。如果有人有其他好的解决方案,请告诉我。

      【讨论】:

        【解决方案4】:

        你也可以先orderBy ...然后keyBy最后values来获得你需要的东西:

        var array = [ { "foo": 1, "bar": 2, "baz": 3 }, { "foo": 1, "bar": 2, "baz": 5 }, { "foo": 1, "bar": 2, "baz": 4 }, { "foo": 2, "bar": 1, "baz": 3 }, { "foo": 2, "bar": 1, "baz": 7 }, { "foo": 1, "bar": 3, "baz": 4 } ]
        
        const result = _.values(_.keyBy(
           _.orderBy(array, ['foo', 'bar', 'baz']), x=>`${x.foo}-${x.bar}`))
        
        console.log(result)
        &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"&gt;&lt;/script&gt;

        或者您也可以通过以下方式chain

        const result = _(array)
          .orderBy(['foo', 'bar', 'baz'])
          .keyBy(x => `${x.foo}-${x.bar}`)
          .values()
          .value()
        

        【讨论】:

          【解决方案5】:

          const array = [
            { foo: 1, bar: 2, baz: 3 },
            { foo: 1, bar: 2, baz: 5 },
            { foo: 1, bar: 2, baz: 4 },
            { foo: 2, bar: 1, baz: 3 },
            { foo: 2, bar: 1, baz: 7 },
            { foo: 1, bar: 3, baz: 4 }
          ];
          
          const result = array.reduce((result, obj) => {
            const resultObj = result.find(resultObj => obj.foo === resultObj.foo && obj.bar === resultObj.bar);
          
            if (!resultObj) {
              return [ ...result, obj ];
            }
          
            if (resultObj.baz > obj.baz) {
              return result;
            }
          
            return [ ...result.filter(obj => obj !== resultObj), obj ];
          }, []);
          
          console.log(result);

          【讨论】:

            猜你喜欢
            • 2020-06-12
            • 2022-06-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-12-07
            • 2015-03-31
            • 2021-10-26
            • 1970-01-01
            相关资源
            最近更新 更多