在包含超过1000万行的字符串中查找重复行(重复一次以上)的最佳方法是什么? (我只是尝试将数组保留为字符串以节省内存)
例如:
输入:
userId256
userId512
userId64
userId256
userId128
userId128
userId128
userId8
userId4
...
输出:
userId256
userId128
我会使用split("\n")
,然后使用数组,但是可能存在使用较大字符串值的最佳方法。
我不确定性能是否会更好,您需要检查它的性能,并与基于阵列的解决方案进行比较。
您可以使用带有capture group,positive lookahead和back reference的RegExp查找重复的行,然后将其转换为Set,然后扩展到数组以获取唯一的行:
const str = `userId256
userId512
userId64
userId256
userId128
userId128
userId128
userId8
userId4`
const result = [...new Set(str.match(/^(.+)$(?=[\s\S]+\1)/gm))]
console.log(result)
编辑
没有一种方法可以在不访问每个元素的情况下神奇地识别出重复项。现在,这是您要在哪里做的问题。由于用户体验不会受到影响,因此在后端上做得特别好。如果仍要在浏览器上使用它,则可以使用setTimeout
或使用webworkers来减少对用户界面的影响。
实际答案
您必须对此可以使用reduce函数。
const str = `your big string`;
const data = str.split("\n");
let duplicate = data.reduce((acc,currentValue,index, array) => {
if(array.indexOf(currentValue)!=index && !acc.includes(currentValue)) acc.push(currentValue);
return acc;
}, []);
console.log(`Duplicates are now in the array ${duplicate}`);
您可以找到类似的重复项:
const result = a.reduce((a, c)=> {
a[c] = a[c] || {data:[]};
a[c].data.push(c);
return a;
}, {});
const duplicates = Object.entries(result).filter(([k, v]) => v.data.length > 1 );
const a = [
'userId256',
'userId512',
'userId64',
'userId256',
'userId128',
'userId128',
'userId128',
'userId8',
'userId4'
];
const result = a.reduce((a, c)=> {
a[c] = a[c] || {data:[]};
a[c].data.push(c);
return a;
}, {});
const duplicates = Object.entries(result).filter(([k, v]) => v.data.length > 1 );
console.log(duplicates);
取决于您要优化的内容(时间/空间/代码复杂度)以及某些情况:
indexOf
搜索。每当获得多个结果时,请记住行内容。这几乎不需要额外的空间,但是运行时间为O(n²)。]为了避免数据的中间副本,您可以创建一个生成器函数,该函数将使您返回一个可迭代的对象: