2维有序数字

时间:2015-03-09 14:54:57

标签: javascript

我有一个问题,对你来说可能很简单,但我不知道如何通过一个简单而强大的解决方案来做到这一点。

所以,让我们考虑一下这样的数字矩形

154784587
251436258
748541254
965874584
521414174

如何抓取它以找到水平或垂直倍数3(例如)? 我想过将它转换为二维数组

var arr = [
  [1,5,4,7,8,4,5,8,7],
  ...
]

然后双循环(水平和垂直)。但这听起来很混乱,你知道我怎么能以干净简单的方式实现这一目标吗?

1 个答案:

答案 0 :(得分:1)

要求

根据您的评论,我理解这一点:

  • 在水平和垂直方向上找到所有可被3整除的值
  • 所有值都包含所有数字的组合。例如,如果一行包含9个项目,则必须考虑所有单个数字,双位数字,三位数字,... 9位数值。

假设

我假设输入值是一个字符串,mapreducefilter方法可用。

输入

var stream = "154784587251436258748541254965874584521414174";
var columns = 9;

助手

需要三名助手:

  • 根据字符串输入将值组合在一起。
  • 一个从字符串中返回一个字符。
  • 创建一个谓词来测试可被3整除的值。
  • 一个用于将字符串解析为整数并提取所有可分的值。

其中一些功能看起来非常简单,但是为了增强代码的可读性,我们完成了这些功能:

function groupChars(stringValue, numberOfCharacters) {
    var regex = new RegExp(".{1," + numberOfCharacters + "}", "g");
    return stringValue.match(regex);
}

function getNthCharacter(stringValue, index) {
    return stringValue[index];
}

function isDivisibleBy(divisor) {
  return function(value) {
    return value % divisor === 0;
  }
}

function getValuesDivisibleBy(stringValues, divisor) {
    return stringValues.map(function(item) {
              return parseInt(item, 10);
          }).filter(isDivisibleBy(3));
}

矩形数据生成

使用这些帮助程序,通过按列数将字符分组在一起来捕获行(或水平)数据。给定一组行,然后可以提取列(或垂直)数据。

function getRowData(stream, columns) {
    return groupChars(stream, columns);
}

function getColumnData(rowData, columns) {
    var columnData = [];
    for (var i = 0; i < columns; i++) {
        columnData.push(rowData.map(function(row) {
            return row[i]
        }).join(''));
    }
    return columnData;
}

创建水平和垂直值的平面数组

然后通过首先提取行然后提取列来从流中提取值。这产生了一个表示行和列值的字符串数组。

function getBoxedData(stream, columns) {
    var data = {};
    data.rows = getRowData(stream, columns);
    data.columns = getColumnData(data.rows, columns);
    return data.rows.concat(data.columns);
}

减少数据集

最后的处理是通过获取每个字符串并根据列数解析数字或数字组来完成的。需要一个循环将值分组为单个数字,两位数和最多n位数值。每个值都被解析为一个整数,然后验证它的可分性为3。

var set = getBoxedData(stream, columns);

var results = set.reduce(function(result, item) {
    for(var i = 0; i < item.length;) {
        var values = groupChars(item, ++i);
        var valuesByDivisibleThree = getValuesDivisibleBy(values, 3);
        result.push.apply(result, valuesByDivisibleThree);
    }
    return result;
}, []);

最终结果:

您可以通过对最终结果应用过滤器来获取所有唯一值。

var stream = "154784587251436258748541254965874584521414174";
var columns = 9;

function groupChars(stringValue, numberOfCharacters) {
  var regex = new RegExp(".{1," + numberOfCharacters + "}", "g");
  return stringValue.match(regex);
}

function getNthCharacter(stringValue, index) {
  return stringValue[index];
}

function isDivisibleBy(divisor) {
  return function(value) {
    return value % divisor === 0;
  }
}

function getRowData(stream, columns) {
  return groupChars(stream, columns);
}

function getColumnData(rowData, columns) {
  var columnData = [];
  for (var i = 0; i < columns; i++) {
    columnData.push(rowData.map(function(row) {
      return row[i]
    }).join(''));
  }
  return columnData;
}


function getValuesDivisibleBy(stringValues, divisor) {
  return stringValues.map(function(item) {
    return parseInt(item, 10);
  }).filter(isDivisibleBy(divisor));
}

function getBoxedData(stream, columns) {
  var data = {};
  data.rows = getRowData(stream, columns);
  data.columns = getColumnData(data.rows, columns);
  return data.rows.concat(data.columns);
}

var set = getBoxedData(stream, columns);

var results = set.reduce(function(result, item) {
  for (var i = 0; i < item.length;) {
    var values = groupChars(item, ++i);
    var valuesByDivisibleThree = getValuesDivisibleBy(values, 3);
    result.push.apply(result, valuesByDivisibleThree);
  }
  return result;
}, []);

console.log(results);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>


出于历史原因的原始答案:

使用2D阵列

也许reducefilter会清理它?不需要循环......即使在后台运行循环。

var dataset = [
  [1, 5, 4, 7, 8, 4, 5, 8, 7],
  [2, 5, 1, 4, 3, 6, 2, 5, 8],
  [7, 4, 8, 5, 4, 1, 2, 5, 4],
  [9, 6, 5, 8, 7, 4, 5, 8, 4],
  [5, 2, 1, 4, 1, 4, 1, 7, 4]
];

function isDivisibleBy(divisor) {
  return function(value) {
    return value % divisor === 0;
  }
}

var divisibleByThree = dataset.reduce(function(accumulator, row) {
  return accumulator.concat(row.filter(isDivisibleBy(3)));
}, []);

console.log(divisibleByThree)
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

直接解析字符串

或者,您可以解析字符串并使用regex进行清理。使用mapfilter也会提供相同的结果。如果您可以作为一维数组访问数据,那么这将是相同的解决方案。

var stream = "154784587251436258748541254965874584521414174";
var data = stream.split(/(?!^)/);

function isDivisibleBy(divisor) {
  return function(value) {
    return value % divisor === 0;
  }
}

var divisibleByThree = data.map(function(item) {
  return parseInt(item, 10);
}).filter(isDivisibleBy(3));

console.log(divisibleByThree);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>