【问题标题】:Looking up value from CSV and return result从 CSV 中查找值并返回结果
【发布时间】:2019-12-08 17:53:48
【问题描述】:

我正在尝试使用 Javascript 在 CSV 文件中查找一个值并返回它的对应值(基本上是 VLOOKUP 在 Excel 中所做的)

我已经能够分别遵循一些将 CSV 数据拉入数组的示例,并且我已经看到了一些在数组中查找数据的示例 - 但对于我的生活,我无法弄清楚如何让两者都工作。

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

mac,name
69167f276e9g,LINE1
69167f276e9f,LINE2

我想做的是从 CSV 中查找 'mac' 值,并返回相应的 'name' 值。

因此,如果我查找 '69167f276e9f',我想取回 LINE2 的值。

[编辑:使用 MauriceNino 的建议添加我尝试过的代码 - 但在 'return result[1] 行出现错误 Uncaught TypeError: Cannot read property '1' of undefined ;' ]:

$.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);

})

【问题讨论】:

  • 请同时发布您的尝试JavaScript 代码。
  • 完成(抱歉,这是我第一次来)

标签: javascript jquery jquery-csv


【解决方案1】:

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

  • 它首先根据您的数据创建一个二维数组
  • 然后它搜索第一个具有指定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);

【讨论】:

  • 感谢您的评论,我尝试使用当前提取 CSV 数据的方式来实现 - 但是我收到 Uncaught TypeError: Cannot read property '1' of undefined at the line '返回结果[1];'
  • 那么你的数据没有像你说的那样格式化@siers82
【解决方案2】:

我刚刚写完一个几乎完全相同的脚本。 我在那里所做的是使用 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]

编辑:我刚刚看到 MauriceNino 的回答,这与我的非常相似。 注意差异:

  1. 在他的回答中,他只使用分隔符进行拆分,在我的情况下,您可以选择在将数据推送到每行的数组之前添加更多计算或修改,并考虑特殊情况,例如当您将分隔符放在由“”包围的值内。这就是为什么我需要使用流方法。

  2. 他的方法非常适合小文件,但将超大文件直接加载到内存可能会很糟糕。我正在处理 15GB 的 csv 文件,所以我不得不使用流。这样我可以加载几行,处理它们并转储我的数据,然后再次加载大量行。

看起来,他的逻辑更适合你的情况,但我不知道你的程序的整个流程或目的,所以我会在这里留下我的答案,让你决定哪个更适合你:)

【讨论】:

    【解决方案3】:

    首先将 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

    【讨论】:

      【解决方案4】:

      听起来你需要一本字典,例如:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-04
        • 1970-01-01
        • 2011-08-26
        相关资源
        最近更新 更多