从CSV查找值并返回结果



我正在尝试使用JavaScript在CSV文件中查找一个值并返回其相应的值(基本上是Vlookup在Excel中所做的(

我已经能够分别遵循一些将CSV数据拉入数组的示例,而且我已经看到了一些在数组中查找数据的示例 - 但是对于我的一生,我不知道如何弄清楚如何让两个工作。

例如,csv文件stations.csv具有以下数据:

mac,name
69167f276e9g,LINE1
69167f276e9f,LINE2

我想做的就是从CSV查找" Mac"值,然后返回相应的"名称"值。

所以,如果我寻找'69167f276e9f'我想回到值line2。

[edit:添加我尝试使用Mauricenino的建议的代码 - 但是获得错误 undfult typeError:无法在line '返回结果[1]上读取未定义的的属性'1';']:

$.ajax('stations.csv').done(function(data) {
  const lookup = (arr, mac) => {
    let twoDimArr = dataArr.map(el => el.split(',')); // map it to array of arrays of strings (data)
    let result = twoDimArr.filter(el => el[0] == mac)[0]; // Get the first element where the mac matches the first element in the array
    return result[1]; // Return the second element in the array
};
    let dataArr = data.split('n');
    dataArr .shift(); // Remove the first array element (The header)
    let resultMac = lookup(dataArr, "69167f276e9f");
    console.log(resultMac);
})

这是一个可能的解决方案:

  • 它首先从您的数据中创建一个二维数组
  • 然后它搜索将指定Mac作为第一个值
  • 的第一个元素
  • 然后它返回该数组的第二个元素

const data = `mac,name
69167f276e9g,LINE1
69167f276e9f,LINE2`;
const lookup = (arr, mac) => {
    let twoDimArr = dataArr.map(el => el.split(',')); // map it to array of arrays of strings (data)
    let result = twoDimArr.filter(el => el[0] == mac)[0]; // Get the first element where the mac matches the first element in the array
    return result[1]; // Return the second element in the array
}
let dataArr = data.split('n');
dataArr .shift(); // Remove the first array element (The header)
let resultMac = lookup(dataArr, '69167f276e9f');
console.log(resultMac);

我刚刚写完一个脚本几乎完全相同的脚本。我在那做的是我使用readlinefs库流了CSV文件:

csvStream = readline.createInterface({
        input: fs.createReadStream(filePath);
});

然后,我使用readline流库的line事件手动解析CSV的每一行:

decompressedStream.on('line', (line) =>

我的CSV具有特殊的结构,因此我必须对值进行手动解析和对值进行一些修改,但是基本上,想法将您使用line.split和您的分配器分配为"行",然后推动每个值到阵列中的单元格。您得到的是一个数组,其中每个单元格代表CSV线中的一个值,然后您可以将其推到另一个大数组,该数组代表整个CSV,并且每个单元格代表一条线。

之后,您可以使用close事件知道流何时结束:

decompressedStream.on('close', () =>

,然后是使用array.find整个CSV数组来找到您寻找的值:

的问题

let res = csvArray.find(val => val[0] == curMac)

,然后

return res[1]

编辑:我刚刚看到了毛里切尼诺的答案,这与我的回答非常相似。注意差异:

  1. 在他的回答中,他仅使用特定器进行分割,在我的情况下,您可以选择在将数据推到每行的数组之前,对数据进行更多的计算或修改,并考虑到特殊情况,例如在被"包围的值包围。那就是为什么我需要使用流方法。

  2. 他的方法非常适合小文件,但是将极大的文件直接加载到内存可能是不好的。我正在处理15GB CSV文件,因此我必须使用该流。这样,我可以加载几行,对其进行处理并转储我的数据,然后再次加载一条线。

看来,他的逻辑更适合您的情况,但是我不知道您程序的全部流程或目的,因此我将在这里留在这里,以便您决定哪种更适合您:(

首先将CSV转换为对象数组。
比使用 Array.prototype.find()在该数组中找到属性值匹配所需字符串的对象。

const csv2array = (csv, dlm = ',') => {
  const [heads, ...lines] = csv.split('n'), th = heads.split(dlm);
  return lines.map(l => l.split(dlm).reduce((o, c, i) => (o[th[i]] = c.trim(), o), {}));
}
const findInCSV = (csv, p, v) => csv2array(csv).find(k => k[p] === v);
// Getting stuff:
const myCSV = `mac,name
69167f276e9g,LINE1
69167f276e9f,LINE2`;
console.log(findInCSV(myCSV, 'mac', '69167f276e9g'))      // Get entire object by knowing the mac
console.log(findInCSV(myCSV, 'mac', '69167f276e9g').name) // Get name knowing the mac 
console.log(findInCSV(myCSV, 'name', 'LINE1'))            // Get entire object by knowing the name 
console.log(findInCSV(myCSV, 'name', 'LINE1').mac)        // Get mac knowing the name

听起来您需要字典,例如:

var myMappings = {
'69167f276e9f': 'LINE1',
'69167f276e9g': 'LINE2'
};
var myVal = myMappings['69167f276e9g'];
alert(myVal); // prints LINE2

相关内容

  • 没有找到相关文章

最新更新