基本上我要做的是映射这个数组并确定哪些对象满足某个条件。条件是: 获取具有最高值 a+b 的对象,如果有两个对象具有相同的值 a+b,则获取具有最高值 c 的对象。最好的方法是什么?也许减少?
const data = [
{
id: 1,
a: 12,
b: 75,
c: 11,
},
{
id: 2,
a: 65,
b: 14,
c: 32,
},
{
id: 3,
a: 32,
b: 23,
c: 45,
},
{
id: 4,
a: 22,
b: 1,
c: 3,
},
];
已经是第一个基于reduce
的朴素方法,它实现了OP的要求和约束,几乎完全符合OP的要求。
如果没有向化简器提供初始值,则此归约回调函数在第一次调用时传递前两个数组项。该函数应该返回一个值,该值在随后的任何迭代步骤中,将作为函数的第一个参数与当前处理的数组项(即第二个参数)一起传递。
因此,对于 OP 的用例,只需要实现正确的比较,这始终确保预期的返回值......
function getItemWithHighestTotal(result, item) {
const resultTotal = result.a + result.b;
const itemTotal = item.a + item.b;
return (
((resultTotal > itemTotal) && result) ||
((resultTotal < itemTotal) && item) ||
((result.c < item.c) && item) ||
// OP did not define the clause where
// even both `c` values are equal.
result
);
}
console.log(
[{
id: 1,
a: 12,
b: 75,
c: 11,
}, {
id: 2,
a: 65,
b: 14,
c: 32,
}, {
id: 3,
a: 32,
b: 23,
c: 45,
}, {
id: 4,
a: 22,
b: 1,
c: 3,
}].reduce(getItemWithHighestTotal)
);
console.log(
[{
id: 1,
a: 12,
b: 75,
c: 11,
}, {
id: 2,
a: 65,
b: 14,
c: 32,
}, {
id: 3,
a: 32,
b: 23,
c: 45,
}, {
id: 4,
a: 22,
b: 1,
c: 3,
}, {
id: 5,
a: 75,
b: 12,
c: 12,
}].reduce(getItemWithHighestTotal)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
一个简单的for
循环应该可以工作。 循环遍历数组,如果当前对象的a
+b
大于存储对象,则用当前循环对象覆盖存储的对象 - 如有必要,请检查c
。
一个简单的 for 循环会很棒
const data = [
{
id: 1,
a: 12,
b: 75,
c: 11,
},
{
id: 2,
a: 65,
b: 14,
c: 32,
},
{
id: 3,
a: 32,
b: 23,
c: 45,
},
{
id: 4,
a: 22,
b: 1,
c: 3,
},
];
let index,
cHigh = Number.MIN_SAFE_INTEGER,
total = Number.MIN_SAFE_INTEGER;
for (let i = 0; i < data.length; ++i) {
const { a, b, c } = data[i];
if (a + b > total) {
total = a + b;
index = i;
} else if (a + b === total) {
if (c > cHigh) {
cHigh = c;
index = i;
}
}
}
console.log(index);
console.log(data[index]);
data.reduce((res, obj) => {
if (!res) return obj
const { a: resA, b: resB, c: resC } = res
const { a, b, c } = obj
const sumRes = resA + resB
const sum = a + b
if(sum > sumRes) return obj
else if (sum === sumRes) return c > resC ? obj : res
else return res
}, null)
我认为这是可以理解的。
我们使用第一个索引初始化第一个结果。我们做了一个简单的比较游戏
如果你愿意,你可以使用Array#reduce
。
在下文中,acc
累加器用于存储当前已知的最大项目。data
中的每个项目都会访问一次,因此具有O(n)
的时间复杂度。
如果当前项curr
的a + b
值与acc
项的值相同,则我们比较两个项的c
值,并返回具有较大c
的项目。
如果当前项的a + b
值大于acc
中的值,则我们返回curr
作为要枚举的下一个项的acc
。
否则我们返回acc
(因为curr
必须小于acc
)。
一旦data
中的项的枚举完成,reduce
将返回acc
的最终值,这将是"最大"的对象。
const data = [
{ id:1, a:12, b:75, c: 11 },
{ id:2, a:65, b:14, c: 32 },
{ id:3, a:32, b:23, c: 45 },
{ id:4, a:22, b:1, c: 3 } ]
const largest = (arr) =>
arr.reduce((acc, curr) => {
switch(Math.sign((curr.a + curr.b) - (acc.a + acc.b))) {
case 0:
return curr.c > acc.c ? curr : acc
case 1:
return curr
default:
return acc
}})
console.log(largest(data))