简体   繁体   English

在 nodejs 中执行以下操作的更好方法:比较导入的 csv 或对象数组的行中是否存在特定键值对

[英]Better way of doing the following in nodejs: Comparing if specific key value pairs exist in rows of a imported csv or array of objects

Issue:问题:

I want to take an object which has 4 key value pairs and compare it to an array of objects which also contains these 4 keys.我想采用具有 4 个键值对的 object 并将其与也包含这 4 个键的对象数组进行比较。 I want to check if the values for the 4 keys in the array of objects MATCH the values in the reference object.我想检查对象数组中 4 个键的值是否与参考 object 中的值匹配。

Current implementation当前实施

The code below works, as a test it produces an array which checks if the "Code" key value matches that of the reference object "testCheck".下面的代码有效,作为测试,它生成一个数组,检查“代码”键值是否与参考 object“testCheck”的值匹配。 The code should be expanded to also check that the year and month are for current year and month and id from the reference object (I know how to get the year and month from node).应该扩展代码以检查年份和月份是否为当前年份和月份以及来自参考 object 的 ID(我知道如何从节点获取年份和月份)。

What I want to know is there a better way of doing this, something more scale friendly maybe or just better written code?我想知道有没有更好的方法来做到这一点,可能是对规模更友好的东西,或者只是更好的编写代码?

toDB -> in production, this will come from the DB, which admin can dynamically manage through an admin portal. toDB -> 在生产中,这将来自数据库,管理员可以通过管理门户动态管理。

testarr -> this is just a snippet, but in production this will come from an uploaded csv. testarr -> 这只是一个片段,但在生产中这将来自上传的 csv。

testCheck -> in production, this object will be created from data in the DB, which once again should be managed by the admin. testCheck -> 在生产中,这个 object 将从数据库中的数据创建,再次由管理员管理。

Code代码

 let testarr = [ { Account: "1110-000", Description: "Cash - Operating", Amount: "-2,733,864.88", Code: "cat", Year: "2020", Month: "1", ID: "cat12345", }, { Account: "1116-000", Description: "Cash in Trust", Amount: "35,431.85", Code: "cat", Year: "2020", Month: "1", ID: "cat12345", }, { Account: "1170-000", Description: "Petty Cash", Amount: "0", Code: "cat", Year: "2020", Month: "1", ID: "cat12345", }, ]; let toDB = { code: "cat", id: "cat12345" }; let testCheck = { Code: toDB["code"], Year: "2020", Month: "1", Id: toDB["id"], }; confirmTheSame = (data) => { return data.map((x) => { if (x["Code"] === testCheck["Code"]) { return true; } else { return false; } }); }; let result = confirmTheSame(testarr); console.log(result);

EDIT 1编辑 1

Found this works better in mapping the testCheck with the array of objects and produced a arrays of boolean for each row (array of arrays) but maybe not the best way of doing this?发现这在将 testCheck 与对象数组映射时效果更好,并为每一行(数组数组)生成了 boolean 的 arrays,但可能不是最好的方法? Leaving this here for your thoughts..把这个留在这里供你思考..

 confirmTheSame = (data) => { return data.map((x) => { return Object.keys(testCheck).map((y) => { if(x[y]===testCheck[y]){ return true } else{ return false } }); }); };

There are different ways to go about this. go 关于这个有不同的方法。 Utils like lodash can also help make the code cleaner.像 lodash 这样的实用程序也可以帮助使代码更清晰。

Without using lodash, you can use the findIndex function on the array in order to figure out if the object exists or not and return true if the index is greater than -1在不使用 lodash 的情况下,您可以在数组上使用 findIndex function 以确定 object 是否存在,如果索引大于 -1,则返回 true

 const testarr = [ { Account: "1110-000", Description: "Cash - Operating", Amount: "-2,733,864.88", Code: "cat", Year: "2020", Month: "1", ID: "cat12345", }, { Account: "1116-000", Description: "Cash in Trust", Amount: "35,431.85", Code: "cat", Year: "2020", Month: "1", ID: "cat12345", }, { Account: "1170-000", Description: "Petty Cash", Amount: "0", Code: "cat", Year: "2020", Month: "1", ID: "cat12345", }, ]; const toDB = { Code: "cat", ID: "cat12345" }; const testCheck = { Code: toDB.Code, Year: "2020", Month: "1", ID: toDB.ID, }; const confirmTheSame = (arr, obj) => { const today = new Date() const currentYear = today.getFullYear().toString() const currentMonth = today.getMonth().toString() const index = arr.findIndex(x => x.Year === currentYear && x.Month === currentMonth && x.Code === obj.Code && x.ID === obj.ID) return index > -1? true: false }; const result = confirmTheSame(testarr, testCheck) console.log(result);

It sounds like you think you'll only be comparing a specific set of 4 keys, but here's a generalized answer that should allow you to compare an arbitrary number of keys in testCheck :听起来您认为您只会比较一组特定的 4 个键,但这里有一个通用答案,应该允许您比较testCheck中任意数量的键:

function confirmTheSame(obj) {
  // `Id` and `ID` keys are different in the 'test' and 'check' objects,
  // so normalize them here. You could skip this if you know the keys will 
  // always match.
  const newObj = Object.keys(obj).reduce((acc, key) => ({
    ...acc,
    [key.toLowerCase()]: obj[key],
  }), {});

  // Use `Array.every` to check that all the values for the given object match.
  return Object.keys(testCheck).every((key) => (
    // Normalize the key here as well.
    newObj[key.toLowerCase()] === testCheck[key]
  ));
}

Full sample:完整样本:

 let testarr = [ { Account: "1110-000", Description: "Cash - Operating", Amount: "-2,733,864.88", Code: "cat", Year: "2020", Month: "1", ID: "cat12345", }, { Account: "1116-000", Description: "Cash in Trust", Amount: "35,431.85", Code: "cat", Year: "2020", Month: "1", ID: "cat12345", }, { Account: "1170-000", Description: "Petty Cash", Amount: "0", Code: "cat", Year: "2020", Month: "1", ID: "cat12345", }, ]; let toDB = { code: "cat", id: "cat12345" }; let testCheck = { Code: toDB["code"], Year: "2020", Month: "1", Id: toDB["id"], }; function confirmTheSame(obj) { const newObj = Object.keys(obj).reduce((acc, key) => ({...acc, [key.toLowerCase()]: obj[key], }), {}); return Object.keys(testCheck).every((key) => ( newObj[key.toLowerCase()] === testCheck[key] )); } console.log(testarr.map(confirmTheSame));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM