需要帮助在JSON文件(node.js)中的列中查找最大值

时间:2017-03-15 03:42:23

标签: node.js

我的地球物理学课程计算任务;该任务基本上是找到txt文件列中最大的值(该值是地震的大小,该文件包含1990 - 2000年的所有地震)。然后取这些地震的纬度和经度,并将其绘制成地图。 这个任务在python中很简单,但是由于我正在花费一些空闲时间来学习webdev,我正在考虑制作一个简单的webapp来完成整个任务。

换句话说,我会上传一个文件,它会自动将最大的地震指定到谷歌地图。

但是因为我在node.js中是一个菜鸟,所以我很难开始这个项目,所以我把它分成几部分,我需要帮助它的第一部分。

我正在考虑将带有数据的txt.file转换为.csv文件,然后将其转换为.json文件。我完全不知道我应该使用什么算法来扫描.json文件并找到给定列的最大值。

以下是原始.txt文件的第一行:

1 5 0 7.0 274 102.000 -3.000

这是在.csv文件上,使用在线转换器:

1 5 0 7.0 274 102.000 -3.000

此处它位于.json文件上,再次使用在线转换器:

1\t 5\t 0\t7.0\t274\t102.000\t -3.000

基本上我需要扫描所有行并找到第5列的最大值。

关于如何开始编写此代码的任何帮助?

非常感谢。

TLDR版本:

需要在包含多行的JSON文件中找到第5列的最大值。

2 个答案:

答案 0 :(得分:1)

我有一个单线,代码高尔夫风格。我会忽略通常的“不要让Stack Overflow为你做功课”。这些天你只是欺骗自己,孩子们,yada yada。

拆分,映射,缩小。

let data = require('fs').readFileSync('renan/homework/geophysicist_data.txt')

let biggest = data.split('\n')
                  .map(line => line.split(/[ ]+/)[4])
                  .reduce((a, b) => Math.max(a, b))

加载data后,我们分三步处理。

  1. .split('\ n')通过拆分换行符,我们将文本文件分解为一个数组,以便将文本文件中的每一行转换为数组中的一个项目。
  2. .map(line => line.split(/ [] + /)[4])'map'获取此行数组并在每一行上运行命令单独。对于每一行,我们告诉它一个或多个空格(split(/[ ]+/))是列分隔符,一旦它被分成列以获取该行中的第五列(我们使用[4]代替[5]因为javascript从0开始计数。
  3. .reduce((a,b)=> Math.max(a,b))现在我们有一个只包含第五列数的数组,我们可以将数组直接发送到{ {1}}让它为我们计算答案的辛勤工作。万岁!
  4. 如果这个数据甚至有点不均匀,那么很容易打破这个,但我假设是因为这是一个家庭作业并非如此。

    祝你好运!

答案 1 :(得分:0)

如果您的文件只包含具有相同结构的数字的行,则我不会将其转换为csv或json。

我只是手动解析.txt。以下是您可以执行此操作的代码段。我使用了2个外部模块:lodash(用于数据操作的超流行的unility库)和验证器(有助于验证字符串):



'use strict';

const fs = require('fs');
const _ = require('lodash');
const os = require('os');
const validator = require('validator');

const parseLine = function (line) {
	if (!line) {
		throw new Error('Line not passed');
	}

	//Splitting a line into tokens
	//Some of tokens are separated with double spaces
	//So using a regex here
	let tokens = line.split(/\s+/);

	//Data validation
	if (!(
			//I allowed more tokens per line that 7, but not less
			tokens && tokens.length >= 7
			//Also checking that strings contain numbers
			//So they will be parsed properly
			&& validator.isDecimal(tokens[4])
			&& validator.isDecimal(tokens[5])
			&& validator.isDecimal(tokens[6])
		)) {
		throw new Error('Cannot parse a line');
	}

	//Parsing the values as they come as string
	return {
		magnitude: parseFloat(tokens[4]),
		latitude: parseFloat(tokens[5]),
		longitude: parseFloat(tokens[6])
	}
};

//I passed the encoding to readFile because if I would not
//data would be a buffer, so we'd have to call .toString('utf8') on it.
fs.readFile('./data.txt', 'utf8', (err, data) => {
	if (err) {
		console.error(err.stack);
		throw err;
	}

	//Splitting into lines with os.EOL
	//so our code work on Linux/Windows/Mac
	let lines = data.split(os.EOL);
	if (!(lines && lines.length)) {
		console.log('No lines found.');

		return;
	}

	//Simple lodash chain to parse all lines
	//and then find the one with max magnitude
	let earthquake = _(lines)
		.map(parseLine)
		.maxBy('magnitude');

	//Simply logging it here
	//You'll probably put it into a callback/promise
	//Or send as a response from here
	console.log(earthquake);
});