在多维数组中找到两个相关数字的最接近组合

Posted

技术标签:

【中文标题】在多维数组中找到两个相关数字的最接近组合【英文标题】:Find the closest combination of two related numbers in a multidimensional array 【发布时间】:2019-01-16 17:59:33 【问题描述】:

我需要根据用户输入在多维数组中搜索和比较两个数字的最接近组合。

目前我有类似的东西可以找到最接近的匹配数字,比如“一个数字”。

var count= [10, 20, 30, 40],

  goal = userinput

  var closest = count.reduce(function(prev, curr) 
    return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
  );

$('#result').attr('value', closest);

我想做什么:当用户在userinput14中输入19时 在 userinput2 中,它应该在多维数组 counts 中搜索和比较最近的数字组合。

<input id="userinput1 " value="19" type="text">
<input id="userinput2 " value="4" type="text">

-

var userinput1 = $('#userinput1 ').val();
var userinput2 = $('#userinput2 ').val();

counts = [['10', '5'], ['20', '10']];

goal = [[userinput1, userinput2]];

/* NEEDED SCRIPT */

$('#result1').attr('value', closest1);
$('#result2').attr('value', closest2);

在这个例子中,它应该选择 ['20', '10'] 并在不同的变量中输出这两个数字。

html 结果应该是:

<input id="result1" value="20" type="text">
<input id="result2" value="10" type="text">

【问题讨论】:

*** 不是免费的编码服务。 SO希望您try to solve your own problem first。请更新您的问题以在minimal reproducible example 中显示您已经尝试过的内容。如需更多信息,请参阅How to Ask,并拨打tour :) 如果input1 接近一个元素的第一个数字,而input2 接近另一个元素的第二个数字怎么办?您如何确定两个数字的接近程度?如果你能想出一个组合公式,那么你就可以使用与处理一个输入时相同的解决方案。 为什么目标是双重嵌套数组? [[userinput1, userinput2]] 而不是 [userinput1, userinput2]? 您是否希望将每个用户输入与值进行比较,或者顺序是否重要,并且 unser 输入应该与内部计数的相同索引进行比较? 我刚刚实现了将一个数字与另一个数字进行比较。双重嵌套数组没有具体原因。我只是认为这是必要的。 【参考方案1】:

为了比较索引方式的绝对 depats,您可以先获取增量,然后根据总和返回数组。

const addAbsDelta = g => (s, v, i) => s + Math.abs(v - g[i]);

var counts = [[10, 5], [20, 10]],
    goal = [19, 4],
    result = counts.reduce((a, b) =>
        a.reduce(addAbsDelta(goal), 0) < b.reduce(addAbsDelta(goal), 0) ? a : b
    );
    
console.log(result);

为了获得其中一个值匹配的结果,您需要获得绝对增量的乘积和绝对增量的总和以获得结果的顺序并取最小值。

function getApproximation(counts, goal) 
    const
        p = (r, v, i) => r * Math.abs(v - goal[i]),   // moves zeros to top
        s = (r, v, i) => r + Math.abs(v - goal[i]),   // allowes sorting
        score = a => a.reduce(p, 1) + a.reduce(s, 0); // get product and sum

    return counts
        .filter(a => goal.every((g, i) => a[i] >= g))
        .reduce((a, b) => score(a) <= score(b) ? a : b);


var counts = [[5300, 4.2], [6800, 6.0], [5650, 6.6], [2600, 7.0], [4700, 7.0], [3250, 7.3], [3800, 7.5], [3300, 7.8], [9000, 8.2], [5700, 8.5], [7400, 8.5], [6900, 8.7], [4300, 9.0], [5000, 9.5], [6000, 9.5], [7700, 9.5], [2750, 10.0], [5300, 10.0], [6500, 10.0], [8900, 10.5], [6800, 11.0], [3600, 11.4], [4500, 11.5], [9500, 11.5], [5700, 12.0], [5000, 24.0], [6500, 27.0], [7900, 30.0], [5700, 31.0]];

console.log(getApproximation(counts, [2000, 5]));  // [2600, 7]
console.log(getApproximation(counts, [2000, 30])); // [7900, 30]
console.log(getApproximation(counts, [2600, 30])); // [7900, 30] 

【讨论】:

非常感谢!这很好用。我如何提供最接近组合的两个数字总是大于目标? 你有例子吗? 我怎样才能实现它搜索最接近的组合,其中两个值总是相同或大于目标?因此,当我搜索 [200,10] 并且有 [190,8] 和 [220,12] 时,它应该选择 [220,12],因为目标高于 [190,8]。 如果总是这样,您可以先过滤较小/不需要的值。 console.log的情况下(getApproximation(counts, [2600, 30]));它选择 [2600, 7]。我怎样才能避免这种情况并实现结果 [7900, 30]?【参考方案2】:

只需添加相应数组元素的差异,并像以前一样将其最小化。

var userinput1 = $('#userinput1 ').val();
var userinput2 = $('#userinput2 ').val();

counts = [
  ['10', '5'],
  ['20', '10']
];

goal = [userinput1, userinput2];

let closest = counts[0];
let prevDiff = Math.abs(closest[0] - goal[0]) + Math.abs(closest[1] - goal[1]);
counts.forEach(c => 
  let curDiff = Math.abs(c[0] - goal[0]) + Math.abs(c[1] - goal[1]);
  if (curDiff < prevDiff) 
    closest = c;
    prevDiff = curDiff;
  
);

$('#result1').val(closest[0]);
$('#result2').val(closest[1]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Input:
<input id="userinput1 " value="19" type="text">
<input id="userinput2 " value="4" type="text">
Output:
<input id="result1" type="text">
<input id="result2" type="text">

【讨论】:

以上是关于在多维数组中找到两个相关数字的最接近组合的主要内容,如果未能解决你的问题,请参考以下文章

php两个多维数组组合遍历

合并多维数组

如何添加来自不同数组的多维数组值

从多维数组中删除数组的最有效方法[重复]

在多维数组和单个数组之间存储数据的最有效方法是啥?

在多维数组上使用 numpy.argmax()