在对象数组的多个属性中获取最接近的较大值

时间:2018-11-08 08:10:36

标签: javascript sorting lodash

我有这个对象数组。

var priceArray = [ 
  { "foo": 1, "bar": 2, "price": 3 },
  { "foo": 2, "bar": 123, "price": 124 },
  { "foo": 2, "bar": 2, "price": 5 },
  { "foo": 112, "bar": 2, "price": 75 },
  { "foo": 2, "bar": 3, "price": 5 },
  { "foo": 3, "bar": 2, "price": 3 },
  { "foo": 3, "bar": 4, "price": 7 },
  { "foo": 4, "bar": 3, "price": 4 },
  { "foo": 4, "bar": 4, "price": 6 }
];

我还有另一个对象数组。

var dataArray = [ 
  { foo: 0.25, bar: 1 },
  { foo: 0.5, bar: 1 },
  { foo: 1, bar: 1 },
  { foo: 1, bar: 2 },
  { foo: 2, bar: 1 },
  { foo: 2, bar: 2 },
  { foo: 2, bar: 4 },
  { foo: 3, bar: 2 },
  { foo: 4, bar: 1 },
  { foo: 4, bar: 2 },
  { foo: 4, bar: 4 },
];

我想在dataArray中添加price,其中价格行foobar的值在priceArray中最接近。

例如-过滤后的数据应这样

var filterDataArray = [ 
  { foo: 0.25, bar: 1, price: 3 },
  { foo: 0.5, bar: 1, price: 3 },
  { foo: 1, bar: 1, price: 3 },
  { foo: 1, bar: 2, price: 3 },
  { foo: 2, bar: 1, price: 5 },
  { foo: 2, bar: 2, price: 5 },
  { foo: 2, bar: 4, price: 7 },
  { foo: 3, bar: 2, price: 3 },
  { foo: 4, bar: 1, price: 4 },
  { foo: 4, bar: 2, price: 4 },
  { foo: 4, bar: 4, price: 6 },
];

如果我借助这些代码对priceArrayfoobar值进行排序,然后使用dataArray过滤此数组。因此,我没有解决方案。就像-

priceArray = priceArray.sort(function(a, b) {
  return a.foo - b.foo || a.bar - b.bar;
});
  or
priceArray = _.sortBy(( _.sortBy(priceArray, 'bar')), 'foo');
  or
priceArray = _.orderBy(priceArray, ['foo', 'bar'], ['asc', 'asc']);

// create new data array with price
const dataNewArray = [];
dataArray.map(dataObj => {
  const dataNewObj = {};
  for(const priceObject of priceArray) {
    if (dataObj.foo <= priceObject.foo && dataObj.bar <=  priceObject.bar) {
        dataNewObj.foo = dataObj.foo;
        dataNewObj.bar = dataObj.bar;
        dataNewObj.price = priceObject.price;
        break;
    }
  }
  dataNewArray.push(dataNewObj);
});

但解决方案是

dataNewArray = [ 
  { foo: 0.25, bar: 1, price: 3 },
  { foo: 0.5, bar: 1, price: 3 },
  { foo: 1, bar: 1, price: 3 },
  { foo: 1, bar: 2, price: 3 },
  { foo: 2, bar: 1, price: 5 },
  { foo: 2, bar: 2, price: 5 },
  { foo: 2, bar: 4, price: 124 },
  { foo: 3, bar: 2, price: 3 },
  { foo: 4, bar: 1, price: 4 },
  { foo: 4, bar: 2, price: 4 },
  { foo: 4, bar: 4, price: 6 } 
];

因此,您可以在此对象{ foo: 2, bar: 4, price: 124 }中看到,price应该是7,而不是124

如何借助Lodash等任何js功能或任何算法来解决我的问题。我在StackOverflow尝试了许多解决方案,但为对象中的单个属性提供了最大的解决方案。

1 个答案:

答案 0 :(得分:3)

您需要按商品的几何距离排序,然后选择第一个匹配的商品。

var priceArray = [{ foo: 1, bar: 2, price: 3 }, { foo: 2, bar: 123, price: 124 }, { foo: 2, bar: 2, price: 5 }, { foo: 112, bar: 2, price: 75 }, { foo: 2, bar: 3, price: 5 }, { foo: 3, bar: 2, price: 3 }, { foo: 3, bar: 4, price: 7 }, { foo: 4, bar: 3, price: 4 }, { foo: 4, bar: 4, price: 6 }],
    dataArray = [{ foo: 0.25, bar: 1 }, { foo: 0.5, bar: 1 }, { foo: 1, bar: 1 }, { foo: 1, bar: 2 }, { foo: 2, bar: 1 }, { foo: 2, bar: 2 }, { foo: 2, bar: 4 }, { foo: 3, bar: 2 }, { foo: 4, bar: 1 }, { foo: 4, bar: 2 }, { foo: 4, bar: 4 }], 
    result;

priceArray.sort((a, b) => 
    (Math.pow(a.foo, 2) + Math.pow(a.bar, 2)) - (Math.pow(b.foo, 2) + Math.pow(b.bar, 2))
);
result = dataArray.map(({ foo, bar }) => ({
    foo,
    bar,
    price: priceArray.find(o => o.foo >= foo && o.bar >= bar).price
}));

console.log(result);     // the result
console.log(priceArray); // the sorted array
.as-console-wrapper { max-height: 100% !important; top: 0; }