简体   繁体   English

只推送一次数组而不是每次满足条件时推送到数组

[英]Only Push onto array once versus pushing to array every time condition is met

I am importing excel files that contain customer orders like so我正在导入包含像这样的客户订单的 excel 文件

onFileChange(event: any) {
    const inputFile: DataTransfer = <DataTransfer>(event.target); 
    const fileReader: FileReader = new FileReader();
    fileReader.onload = (event: any) => {
      const binaryString: string = event.target.result;
      const workBook: XLSX.WorkBook = XLSX.read(binaryString, { type: 'binary', sheetStubs: true}); 
      /* sheetstubs true supposedly shows empty cells but isn't */
      console.log(typeof binaryString)

      const workSheetName: string = workBook.SheetNames[0];
      console.log(workSheetName)
      const workSheet: XLSX.WorkSheet = workBook.Sheets[workSheetName];

      this.data = <Array>(XLSX.utils.sheet_to_json(workSheet, { header: 1, blankrows: true }));


    };
    fileReader.readAsBinaryString(inputFile.files[0]);
    console.log(this.data)
  }

The way the excel files are imported an object of arrays where each array is a row of the excel sheet.导入 excel 文件的方式是数组对象,其中每个数组都是 Excel 工作表的一行。

In the following code snippet, I am searching for items in a column to identify the column in an excel sheet that has the shoe brands requested by a customer in the code在以下代码片段中,我正在搜索列中的项目以标识 Excel 表中包含客户在代码中请求的鞋类品牌的列

for (var i=0; i<this.data.length; i++){
      if (this.data[i].indexOf('Adidas') != -1) {
        var manIndex = this.data[i].indexOf('Adidas')
        for( var j = 0; j<this.data.length; j++){
          this.manufactArray.push(this.data[j][manIndex])
        }

      }
      else if (this.data[i].indexOf('Puma') != -1) {
        var manIndex = this.data[i].indexOf('Puma')
        for (var j=0; j<this.data.length; j++) {
          this.manufactArray.push(this.data[j][manIndex])
        }
      }
      else if (this.data[i].indexOf('Nike') != -1) {
        var manIndex = this.data[i].indexOf('Nike')
        for(var j = 0; j<this.data.length; j++){
          this.manufactArray.push(this.data[j][manIndex])
        }
      }
      }

    }

this works in that it pushes all of the items in the relevant column into the array but it does so every time the conditions are met and as such the same column is pushed into the array a bunch of times as opposed to only pushing the column items once.这是有效的,因为它将相关列中的所有项目推送到数组中,但每次满足条件时都会这样做,因此同一列会多次推送到数组中,而不是只推送列项目一次。 Is there a way maybe using the % or other function so that the column is only pushed into the array one time?有没有一种方法可以使用%或其他函数,以便将列仅推入一次数组? So if I had a customer sheet come in like this:所以如果我有一个客户表是这样的:

示例订单

I would want the array to have [Nike, Adidas, Puma, Puma, Asics, Nike]我希望阵列有[Nike, Adidas, Puma, Puma, Asics, Nike]

One way is to use a Set.一种方法是使用 Set。 You probably don't want to check if it is in the array before you add it, because then you may have O(n²) time complexity, which can be undesirable.您可能不想在添加之前检查它是否在数组中,因为那样您的时间复杂度可能为 O(n²),这可能是不可取的。

You can add it to a set, and return as a set, or if needed, return as an array:您可以将其添加到集合中,并作为集合返回,或者如果需要,作为数组返回:

 const mySet = new Set(); mySet.add(123); console.log([...mySet]); mySet.add("hello world"); console.log([...mySet]); mySet.add(123); console.log([...mySet]);

I would have just used console.log(mySet) but for some reason StackOverflow can't print out its value (unlike Node.js or Chrome).我本来会使用console.log(mySet)但由于某种原因 StackOverflow 无法打印出它的值(与 Node.js 或 Chrome 不同)。 But then it shows how to convert the set back to an array.但随后它显示了如何将集合转换回数组。 You can also use Array.from(mySet) .您还可以使用Array.from(mySet)

So in your code, you probably have:所以在你的代码中,你可能有:

this.manufactSet = new Set();

and in the loop:并在循环中:

this.manufactSet.add(this.data[j][manIndex]);

and after the loop, you can set it back to an array:在循环之后,您可以将其设置回数组:

this.manufactArray = [...this.manufactSet];

But I don't quite get your code:但我不太明白你的代码:

for (var i=0; i<this.data.length; i++){
      if (this.data[i].indexOf('Adidas') != -1) {
        var manIndex = this.data[i].indexOf('Adidas')
        for( var j = 0; j<this.data.length; j++){
          this.manufactArray.push(this.data[j][manIndex])
        }

Why when you found Adidas , then you push everything into the result?为什么当你找到Adidas ,你把所有的东西都推到了结果中? Shouldn't you do:你不应该这样做:

for (var i=0; i<this.data.length; i++){
      if (this.data[i].indexOf('Adidas') != -1) {
        var manIndex = this.data[i].indexOf('Adidas')
        this.manufactArray.push(this.data[i][manIndex])

? ?

Is this.data[i] a string that might have "Cool Adidas NMD hard to find"... and once you find the "location" of Adidas , why do you just push that character into the result? this.data[i]是一个字符串,可能有“很难找到酷的阿迪达斯 NMD”……一旦你找到了Adidas的“位置”,为什么你只是把这个字符推到结果中?

Don't you want to push the whole string into the result?您不想将整个字符串推入结果中吗?

for (var i=0; i<this.data.length; i++){
      if (this.data[i].indexOf('Adidas') != -1) {
        var manIndex = this.data[i].indexOf('Adidas')
        this.manufactArray.push(this.data[i])

So after checking what data[i] is and what you would like to do, seems like this is what you want to do:因此,在检查了 data[i] 是什么以及您想要做什么之后,似乎这就是您想要做的:

Note that you mentioned you actually want the manufacturer to appear more than once, like ["Adidas", "Adidas", "Nike", "Puma", "Nike"] , so I won't use a set as the result below:请注意,您提到您实际上希望制造商出现不止一次,例如["Adidas", "Adidas", "Nike", "Puma", "Nike"] ,所以我不会使用一组作为下面的结果:

const someManufacturers = new Set(['Adidas', 'Puma', 'Nike']);

function getColumnNumber() {
  for (var i = 0; i < this.data.length; i++) {
    for (var j = 0; j < this.data[i].length; j++) {
      if (someManufacturers.has(this.data[i][j])) return j;
    }
  }
}
var manufacturerColumnNumber = getColumnNumber();

for (var i = 0; i < this.data.length; i++) {
  this.manufactArray.push(this.data[i][manufacturerColumnNumber]);
}

Actually, there is a better way to write it now in ES6:实际上,现在在 ES6 中有更好的编写方式:

const someManufacturers = new Set(['Adidas', 'Puma', 'Nike']);

function getColumnNumber() {
  for (const row of this.data) {
    for (let i = 0; i < row.length; i++) {
      if (someManufacturers.has(row[i])) return i;
    }
  }
}
var manufacturerColumnNumber = getColumnNumber();

for (const row of this.data) {
  this.manufactArray.push(row[manufacturerColumnNumber]);
}

I think I see what you mean by "pushing" every time instead of once.我想我明白你每次而不是一次“推动”的意思。 You mean if you see Adidas , you push the whole column values to the array, and the next row, you see Nike , and you push the whole column values to the array again.您的意思是,如果您看到Adidas ,则将整个列值推送到数组,在下一行看到Nike ,然后再次将整个列值推送到数组。 You could have just returned if you put that in a function.如果你把它放在一个函数中,你可能刚刚返回。 So once you see Adidas , then just push all values in that column to the array and return from the function.因此,一旦您看到Adidas ,只需将该列中的所有值推送到数组并从函数返回。

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

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