基于 Array#reduce 如何识别最符合某些特定约束的数组项?



基本上我要做的是映射这个数组并确定哪些对象满足某个条件。条件是: 获取具有最高值 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)的时间复杂度。

如果当前项curra + 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))

最新更新