数组.includes方法对字符串'sku'返回始终为false的奇怪行为

3
我遇到了数组.includes功能的奇怪行为。我的工作是检查变量feedProduct是否具有所有所需字段。
function hasAllRequiredFields(requiredFields, feedProduct) {
    
    // Prepare array for adding missing fields
    let missing_required = [];
    
    // Print all fields and there type (only for easier debugging)
    console.log(feedProduct);
    console.log(typeof feedProduct);
    feedProduct.forEach(fp => {
        console.log(fp)
        console.log(typeof fp)
    })
    
    // Check if feedProduct array contains all required fields
    console.log('')
    console.log('CHECK IF ALL REQUIRED FIELDS ARE PRESENT')
    requiredFields.forEach(wf => {
        console.log(wf);
        console.log(typeof wf);
        if (!feedProduct.includes(wf)) {
            missing_required.push(wf);
        }
    })
    
    console.log('')
    console.log('')
    console.log('Missing')
    console.log(missing_required)
    
    return missing_required;
}

结果非常奇怪。正如您所看到的,我正在在包含字符串“sku”的类型为String的数组FeedProduct中搜索字符串“sku”类型的字符串,但feedProduct.includes(wf)返回false。

sku missing

我也尝试使用indexOf相同的逻辑,结果是相同的。如果我在开发者工具中复制/粘贴此代码,则结果将为true,并且不会缺少任何字段。
请问还有什么其他需要检查或执行的操作,以便我的代码能正常工作?如果您需要任何其他信息,请告诉我,我会提供。谢谢
**更新
该函数在其他函数中被调用,如下所示
let hasRequiredFields = hasAllRequiredFields(preparedMappingFields.storeFeedMustHaveFields, header);

console.log(feedProduct[0], requiredFields[0], feedProduct[0] === requiredFields[0]); 的结果如下:

sku sku false

** 更新二

console.log(requiredFields[0].split('').map(c => c.charCodeAt(0)))
console.log(feedProduct[0].split('').map(c => c.charCodeAt(0)))

Log 1:
[ 115, 107, 117 ]
Log 2:
[ 65279, 115, 107, 117 ]

1
你能展示一下你是如何调用函数的吗? - Sleepwalker
你能否展示一下 console.log(feedProduct[0], requiredFields[0], feedProduct[0] === requiredFields[0]); 的输出结果? - Nick Parsons
2
@Valor_ 看起来你的两个字符串是不同的(即使它们在视觉上看起来相同),你能检查一下 console.log(requiredFields[0].split('').map(c => c.charCodeAt(0)))console.log(feedProduct[0].split('').map(c => c.charCodeAt(0))) 的输出吗? - Nick Parsons
你说得对!它们不一样!请检查更新后的问题 :) - Valor_
1
@Valor_ 你的 feedProduct 数组包含一个由零宽不换行空格字符(65279)组成的 sku,后面跟着一个 's',因此这两个字符串被视为不同。 - Nick Parsons
显示剩余2条评论
3个回答

2
您只是想找出两个数组之间的差异,因此您可以像这样做...

const rf = ['foo', 'bar', 'baz'];

const fp = ['foo', 'baz']

const difference = rf.filter( x => !fp.includes(x))

console.log(difference)

如果您想要获取交集,您需要这样做...

const rf = ['foo', 'bar', 'baz'];

const fp = ['foo', 'baz']

const intersection = rf.filter( x => fp.includes(x))

console.log(intersection)


1
是的,这可能是更实际的方法,但问题仍然存在。我从CSV文件中获取此产品字段,因此我认为可能与编码或其他方面有关。 - Valor_
@Valor_,哦,好的,那就不同了。你不能只检查一下从解析的CSV文件中获取到的内容吗? - DavidDomain
我已经更新了我的问题。在那里,你会看到那些console.log和字符串不一样:( - Valor_

1

这个函数是可行的。(虽然它可以被优化)

function hasAllRequiredFields(requiredFields, feedProduct) {

  // Prepare array for adding missing fields
  let missing_required = [];

  // Print all fields and there type (only for easier debugging)
  console.log(feedProduct);
  console.log(typeof feedProduct);
  feedProduct.forEach(fp => {
    console.log(fp)
    console.log(typeof fp)
  })

  // Check if feedProduct array contains all required fields
  console.log('')
  console.log('CHECK IF ALL REQUIRED FIELDS ARE PRESENT')
  requiredFields.forEach(wf => {
    console.log(wf);
    console.log(typeof wf);
    if (!feedProduct.includes(wf)) {
      missing_required.push(wf);
    }
  })

  console.log('')
  console.log('')
  console.log('Missing')
  console.log(missing_required)

  return missing_required;
}
var feedProductData = [
  'sku', 'kategorija_proizvoda', 'naziv_proizvoda',
  'proizvodjac', 'specifikacija', 'proizvod_url',
  'cena', 'slika_url', 'dostupnost_proizvoda'
];
var requiredFieldData = ['sku', 'required_and_missed'];
hasAllRequiredFields(requiredFieldData, feedProductData);

我能看到的唯一原因是你的 sku !== sku。添加 trim 应该可以解决这个问题。
优化后的代码

function hasAllRequiredFieldsUpdated(requiredFieldData, feedProductData) {
  return requiredFieldData.filter(x => !feedProductData.includes(x))
}
var feedProductData = [
  'sku', 'kategorija_proizvoda', 'naziv_proizvoda',
  'proizvodjac', 'specifikacija', 'proizvod_url',
  'cena', 'slika_url', 'dostupnost_proizvoda'
];
var requiredFieldData = ['sku', 'required_and_missed'];
var missingFields = hasAllRequiredFieldsUpdated(requiredFieldData, feedProductData);
console.log(missingFields);


1
你遇到的问题是,看起来像"sku"的两个字符串实际上并不相等:在feedProduct数组中的那个包含一个不可见字符。
这个字符,U+FEFF,也称为字节顺序标记,经常放在Unicode文件的开头,以指示正确的字节顺序(字节序)。
我不知道你的数据来自哪里,但是在解析过程中保留了该字符。
最好的方法是将数据文件保存为无BOM,或者如果不可能,就在从文件中读取后立即删除它。
要删除此字符,可以使用以下代码:
const outputString = inputString.replace(/^\uFEFF/, '')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接