【问题标题】:How to build array out of object which contains string?如何从包含字符串的对象构建数组?
【发布时间】:2020-04-23 21:11:37
【问题描述】:

我正在尝试将以下数据结果创建为键/值对,我们如何使用 JS 拆分功能来实现该任务在这里几乎没有卡住。

main.js

const data = [{
        "Row ID  O ID    O Date  Ship Date   Ship Type": "1   PA-152156   11/9/20 01/19/16"
    }

]
    function buildArray(data) {
      for(item in arr) {
      let string = item;
      let array  = string
      .replace(/" "\s/g, '####')
      .split(' ')
      .map(pair => {
        let split = pair.split('####');
        return { key: split[0], value: split[1] };
      });
     }
    }

console.log(buildArray(data));

预期输出

[{
    "Row ID": 1,
    "O ID": "PA-152156",
    "O Date": "11/9/20",
    "Ship Date": "01/19/16"
}]

tsv文件数据

Row ID  O ID    O Date  Ship Date   Ship Type   Customer ID Customer Name   Seg Country City    State   Zip Code    Region  Product ID  Category    Sub-Category    Product Name    Sales   Quantity    Discount    Profit
1   PA-152156   11/9/20 01/19/16    Second Class    CG-125  Clay bute   Consumer    United States   Henderson   Kentucky    42420   South   FUR-BO-10001798 Furniture   Bookcases   Bush, Somerset Collection Bookcase? 261.96  2   0   41.9136

【问题讨论】:

  • 每个列标题之间是否有一定数量的空格?如果是这样,您可以将其分开,但我最终这里的数据结构似乎真的很脆弱。数据不能以 CSV 格式输入吗?
  • @coloradocolby 我正在从 tsv 文件中读取数据,我在上面的示例中添加了 data 来构建数组,现在询问是构建键值对

标签: javascript arrays regex split


【解决方案1】:

我们可以从您的原始数据开始,编写一个将 TSV 字符串(带有标题)转换为对象数组的函数。

这个tsv2arr(与an earlier answer略有不同)通过首先修剪任何前导或尾随空格、在换行符上拆分以及在制表符上拆分每一行来实现这一点。第一行的输出成为标题字段名称,其余的通过获取每个值并将其与同一索引处的标题配对而减少为对象。看起来像数字的值被转换成数字;这可能会转换一些您不想转换的东西,但如果您需要更改它们,您可以对其进行后处理。

代码相当简单:

const tsv2arr = (tsv) => {
  const [headers, ...rows] = tsv .trim () .split ('\n') .map (r => r .split ('\t'))
  return rows .reduce ((a, r) => [
    ... a, 
    Object .assign (... (r .map (
      (x, i, _, c = x.trim()) => ({[headers [i].trim()]: isNaN(c) ? c : Number(c)})
    )))
  ], [])
}

const tsv = `
Row ID	O ID    	O Date	Ship Date	Ship Type	Customer ID	Customer Name	Seg      	Country	        City    	State   	Zip Code	Region	Product ID	Category	Sub-Category	Product Name                    	Sales	Quantity	Discount	Profit
1	PA-152156	11/9/20	01/19/16	Second Class	CG-125  	Clay bute	Consumer	United States	Henderson	Kentucky	42420   	South	FUR-BO-10001798	Furniture	Bookcases	Bush, Somerset Collection Bookcase?	261.96	2        	0        	41.9136
2	ST-621973	8/9/20	02/10/16	First Class	XY-139  	Foobar Inc	Consumer	United States	Madison 	Wisconsin	53702   	Midwest	FUR-SO-10003869	Furniture	Sofas   	Tyler, Some Random Sofa Name    	963.85	1        	0        	265.89
3	MQ-169437	12/7/20	03/15/16	Second Class	CG-125  	Clay bute	Consumer	United States	Henderson	Kentucky	42420   	South	FUR-DE-10005309	Furniture	Desk    	Adams, Some Random Desks Name?  	654.13	1        	0        	143.28
`


console .log (
  tsv2arr (tsv)
)
.as-console-wrapper {min-height: 100% !important; top: 0}

编辑:向单元格添加了trim。这可能不是必需的;这可能只是我格式化输入以排列选项卡的产物。但是很难想象它会伤害任何东西,并且在某些情况下它可能会有所帮助。请注意,源文本中有许多额外的空格,以使列在页面上对齐。当然,它们完全无关紧要,这个trim 摆脱了它们。

另类

如果你真的想从那种输入格式开始,你可以这样写:

const data = [
  {"Row ID	O ID	O Date	Ship Date	Ship Type": "1	PA-152156	11/9/20	01/19/16	Second Class"},
  {"Row ID	O ID	O Date	Ship Date	Ship Type": "2	ST-621973	8/9/2	02/10/16	First Class"}
]

const buildObj = (kv) =>
  Object .entries (kv) .map (([k, v]) => {
    const keys = k .split ('\t')
    const vals = v .split ('\t')
    return Object .assign (... keys .map ((k, i) => ({[k]: vals [i]})))
  })

console .log (
  data .flatMap (buildObj)
)

但这种格式对我来说意义不大,至少作为一种传输格式。如果没有别的,那就太多余了。

我怀疑您的问题是您没有您认为有的标签。程序员的文本编辑器通常配置为用空格替换制表符;这可能就是这里发生的事情。例如,您粘贴到问题中的内容不包括标签。

我建议您尝试解决输入问题并使用更像原始答案的内容。这是一些奇怪数据的解决方法,这些数据可能是您的开发/显示过程的产物,而不是基本的东西。

【讨论】:

  • 如何创建您使用 const tsv 声明的字符串,我正在读取文件并将其转换为字符串 const tsvFileData = fs.readFileSync('./filename1.tsv'); const tsvToStr = tsvFileData.toString(); 并且它的抛出错误 tsv.trim is not a fucntion
  • 返回结果如[ { "Row ID O ID O Date Ship Date Ship Type Customer ID Customer Name Seg Country City State Zip Code Region Product ID Category Sub-Category Product Name Sales Quantity Discount Profit": "1 PA-152156 11/9/20 01/19/16 Second Class CG-125 Clay bute Consumer United States Henderson Kentucky 42420 South FUR-BO-10001798 Furniture Bookcases Bush, Somerset Collection Bookcase? 261.96 2 0 41.9136" }]
  • 我不知道你是怎么得到那种奇怪的格式的。我不知道这是否会有所帮助:fs.readFileSync('./filename1.tsv').toString('utf8')。如果不是,那么我不明白你的输入格式。但是这种中间格式非常可怕。我们可以很容易地修改代码来处理它。但是如果有额外的记录,它会是什么样子?
  • 我试过toString 结果还是一样,不确定它在你提供的sn-p 中是如何工作的,这就是我将它分配给tsv 变量的格式
  • @hussain:我添加了一个替代方案,这可能会有所帮助。但我认为问题与您输入中的选项卡有关。
猜你喜欢
  • 2012-06-09
  • 2020-09-22
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 2011-02-27
  • 2019-06-06
  • 2021-06-20
  • 1970-01-01
相关资源
最近更新 更多