如何处理多个输入值到一个输出值?
function c(input,val){
return input.indexOf(val)>-1;
}
function result(i){
if(c(i,1) && c(i,2) && c(i,3)){
return "alpha";
}else if(c(i,1) && c(i,2) && !c(i,3)){
return "beta";
}else if(c(i,1) && !c(i,2) && c(i,3)){
return "gamma";
}else if(c(i,1) && !c(i,2)){
return "delta";
}else if(c(i,3)){
return "theta";
}
//..... and so on covering all possible combinations
return null;
}
result([1,2,3]); //output : alpha
result([1,3,2]); //output : alpha
result([1,3,1,1]); //output : gamma
result([1,2,4]); //output : beta
result([3]); //output : theta
数组中的值的数量可以是N,但仅来自一组预定义的值
使用这么多组合的正确方法是什么?
答案 0 :(得分:0)
如果案例更容易获取,则可以更清楚地组织代码。例如,alpha
情况可以通过数组[1,2,3]
来表示,该数组将列出代码所依赖的数字和布尔值[true,true,true]
的数组,它们将指示相应的数字是否发生或不。检查可以通过以下功能实现。
function check_case(values,bools){
var Result = true;
for ( var i = 0; i < values.length; i++ ){
Result = Result && ( c(values[i]) == bools[i] );
}
return Result;
}
这规避了c
的结果必须单独否定的条件的制定,这使得它们难以遵循和编辑。
这个想法可以更进一步,通过一系列案例来保存案件的名称。包含上述前两种情况的数组将如下所示。
[
{
values: [1,2,3],
bools: [true,true,true],
name: 'alpha'
},
{
values: [1,2,3],
bools: [true,true,false],
name: 'beta'
}
]
然后代码将遍历此数组,为每个索引调用check_case
并为第一个匹配返回name
的值。
答案 1 :(得分:0)
让你的预定义数组为: - [3,2,1](为了简单起见我保持简短,这可以扩展到N个元素)
预定义数组作为布尔字符串可以显示为: - 123
您可以将此数字视为布尔值并创建所需的输出映射: -
示例: - 如果没有数字: - 000 0
如果只有1: - 100 4
如果只有1和2: - 110 6
等等所有必需的布尔组合都可以定义
因此,对于N个数字,您可以创建所需的所有可能组合的列表
示例: - var definedSet = {&#34; 0&#34;:&#34; Alpha&#34;,&#34; 1&#34;:&#34; beta&#34;,&#34; 2&#34;:&#34;伽马&#34;&#34; 3&#34;:&#34; X&#34;&#34; 4&#34;:&#34; Y&#34 ;, &#34; 5&#34;:&#34; Z&#34;&#34; 6&#34;:&#34;&#34;&#34; 7&#34;:&#34; b& #34;};
现在接受输入并删除重复项并检查位置(数字的位位置并创建一个布尔值并将其映射到定义的集合)
代码: -
function sortAndRemoveDuplicates(arr) {
arr.sort( function(a, b) { return a - b; } );
var copy = arr.slice(0);
arr.length = 0;
for (var i = 0, len = copy.length; i < len; ++i) {
if (i == 0 || copy[i] != copy[i - 1]) {
arr.push(copy[i]);
}
}
return arr;
}
var definedArr = [3,2,1];
var definedSet = {"0":"Alpha","1":"beta","2":"gama","3":"x","4":"y","5":"z","6":"a","7":"b"};
var inputArr=[1,4,3,1,1];
sortAndRemoveDuplicates(inputArr);
var outBooleanValue = 0;
for(var i=0;i<inputArr.length;i++)
{
var numIndex =definedArr.indexOf(inputArr[i]);
if(numIndex!=-1)
{
outBooleanValue+=Math.pow(2,numIndex);
}
}
result =definedSet[outBooleanValue.toString()];
alert(result);
这是工作小提琴: -
以下是此版本的另一个版本,其中不需要预定义输入,它允许您按照指定提供条件: -
var definedSet = {"1":"alpha","12":"beta","12!3":"gama","123":"delta"};
$("#defined-set").html(JSON.stringify(definedSet));
var inputArr=[1,2];
$("#input").html(JSON.stringify(inputArr));
$.unique(inputArr);
inputArr.sort();
var outputStr = inputArr.join('');
var regexStr = '';
var loopCounter=0;
for(loopCounter=0;loopCounter<outputStr.length;loopCounter++)
regexStr+='(!\\d)*'+outputStr[loopCounter]+'(!\\d)*';
regexStr+='$';
//var regexPattern = new RegExp(regexStr);
console.log(regexStr);
for(var currSet in definedSet)
{
//var match = regexPattern.test(currSet);
var match = currSet.search(regexStr);
if(match!=-1)
{
if(currSet==outputStr)
{
$("#result").append("Exact Match::");
}
$("#result").append(currSet+"<br/>");
}
}
以下是工作小提琴的链接: -
注意: - 这只是用于获得答案的算法的基本原型,可以根据编程需要进行修改。
希望这证明是有用的。
答案 2 :(得分:0)
根据Condor的回答,以下内容应该可以胜任。它使用一系列测试来计算结果,并实现“非”测试。如果值为“true”,则必须出现,如果值为“false”,则不得出现。如果没有提及,那么它是否在值中无关紧要。
重复不是问题,在一个失败之前处理值。首先删除重复项可能会加快它的速度。
结果是第一组测试的名称。
function testValues(values) {
var checks = [
{alpha: {1:true, 2:true, 3:true }},
{beta : {1:true, 2:true, 3:false}},
{gamma: {1:true, 2:false, 3:true }},
{theta: {3:true}}
];
var check, resultName, tests, passed;
// Do checks in sequence
for (var i=0, iLen=checks.length; i<iLen; i++) {
check = checks[i]
// Get name of result to return if the checks pass
for (resultName in check) {
// Make sure result is own property
if (check.hasOwnProperty(resultName)) {
// Passed is true until a fail is found
passed = true;
// Get tests to perform
tests = check[resultName];
// For each value in tests, make sure value exists or doesn't in values
for (var v in tests) {
if (tests.hasOwnProperty(v)) {
// Only test if passed is true
if (passed) {
// Note that indexOf uses === so must have same type
// Property names are always strings so if passing numbers,
// Must convert to numbers
passed = tests[v] === (values.indexOf(+v) != -1);
}
}
}
// If passed tests, return
if (passed) return resultName;
}
}
}
return 'failed all tests...';
}
console.log(testValues([1,2,3])); //output : alpha
console.log(testValues([1,3,2])); //output : alpha
console.log(testValues([1,3,1,1])); //output : gamma
console.log(testValues([1,2,4])); //output : beta
console.log(testValues([3])); //output : theta
如果 Object.keys 与 forEach 一起使用,代码可能会更短一些,但上面的内容更清晰一点(可能),它可以重构为短。如果提供 Array.prototype.indexOf 的垫片,上述内容将适用于ECMA-262 ed 3环境。
如果使用现代功能,可以简化代码。为旧版浏览器提供支持并不困难:
// These are sufficient to support the function but are not suitable for general use
// Better versions are avaialble at MDN, see links below
if (!Object.keys) {
Object.keys = function(obj) {
var keys = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
keys.push(key);
}
}
return keys;
};
}
if (!Array.prototype.indeOf) {
Array.prototype.indexOf = function (value) {
for (var i=0, iLen=this.length; i<iLen; i++) {
if (this[i] === value) return i;
}
return -1;
};
}
function testValues(values) {
var checks = [
{alpha: {1:true, 2:true, 3:true }},
{beta : {1:true, 2:true, 3:false}},
{gamma: {1:true, 2:false, 3:true }},
{theta: {3:true}}
];
var check, passed, resultName, tests, testKeys;
for (var i=0, iLen=checks.length; i<iLen; i++) {
check = checks[i]
resultName = Object.keys(check)[0];
passed = true;
tests = check[resultName];
testKeys = Object.keys(tests);
for (var j=0, jLen=testKeys.length; j<jLen && passed; j++) {
passed = tests[testKeys[j]] === (values.indexOf(+testKeys[j]) != -1);
}
if (passed) return resultName;
}
return 'failed all tests...';
}
Object.keys:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Array.prototype.indexOf:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
答案 3 :(得分:0)
此解决方案假定输入中元素的顺序并不重要。也就是说,[1, 3, 2]
的输入与[1, 2, 3]
的输入相同。
看起来你要做的就是从范围(1..n)
中获取一组可能的输入,每个输入可能存在也可能不存在。换句话说,对于范围[1, 2, 3, 4]
,一个可能的输入将是[1, 3]
。或者,
Out of: [1, 2, 3, 4]
We want: [x, 0, x, 0]
这看起来很像二进制数,特别是如果我们颠倒了订单。所以我们真正需要做的就是
对于第一部分,我们需要做的是循环输入值和OR
相应的位。这也会自动处理任何重复。
for (i=0;i<input_array.length;i++)
{
num = num | (1 << (input_array[i] - 1));
}
- 1
因为我们的序列是从1
而不是0
开始的。因此,4
的输入将生成1000
,2
的输入将生成0010
。 OR
- 将它们放在一起会给我们1010
或10(十进制)。
现在num包含我们预先设置的表的索引:
values[0] = "alpha"; // Corresponding to input []
values[1] = "beta"; // Corresponding to input [1]
...
values[10] = "gamma"; // Corresponding to input [4, 2] - remember, it's reversed
...
values[15] = "theta"; // Corresponding to input [4, 3, 2, 1]