【问题标题】:Remove duplicates from JavaScript array using Python使用 Python 从 JavaScript 数组中删除重复项
【发布时间】:2020-01-24 01:35:36
【问题描述】:

假设我有一个 JavaScript 元素数组,看起来非常类似于:

var oui = new Array({
    "pfx": "000000",
    "mask": 24,
    "desc": "00:00:00   Officially Xerox, but 0:0:0:0:0:0 is more common"
},{
    "pfx": "000001",
    "mask": 24,
    "desc": "Xerox  Xerox Corporation"
},{
    "pfx": "000002",
    "mask": 24,
    "desc": "Xerox  Xerox Corporation"
},{
    "pfx": "000003",
    "mask": 24,
    "desc": "Xerox  Xerox Corporation"
},{
    "pfx": "000004",
    "mask": 24,
    "desc": "Xerox  Xerox Corporation"
},{
    "pfx": "000004",
    "mask": 24,
    "desc": "Let's pretend this is a repeat"
   });

现在想象一下,文件非常大,一些“pfx”值在整个数据集中重复出现。显然,手动重复数据删除是不可能的,所以我试图找出以编程方式处理它的最佳方法。如何编写 python 脚本来读取包含此数据集的 .JS 文件以进行重复数据删除和删除任何重复项?换句话说,我想读入 JS 文件,解析数组,并生成另一个具有类似数组的 JavaScript 文件,但 pfx 变量只有唯一值。

我已经解决了其他几个本质上相似的 Stack Overflow 问题,但似乎没有什么适合这种情况。在我的 python 测试中,我很少能自己获取 pfx 变量来删除重复项,或者 Python 难以将其作为正确的 JSON 对象读入(即使没有“var”和“new Array”部分)。我还应该注意,我在 Python 中对 JS 文件中的另一个 JavaScript 函数进行重复数据删除(我尝试遵循 this 之类的示例)的原因是它只会夸大具有加载到页面上。

在未来,该数组可能会继续增长——因此为了避免不必要的 JavaScript 加载以保持页面响应时间快,我认为这是一个可以而且应该离线执行并添加到页面的步骤.

为了澄清,这里是我试图模拟的网站模型:https://www.wireshark.org/tools/oui-lookup.html。它本质上非常简单。

研究:

Convert Javascript array to python list?

Remove duplicate values from JS array

【问题讨论】:

  • 如果结构不是嵌套的,我会用正则表达式匹配第一个{到最后一个},然后使用re.sub,解析JSON,在Python中重复数据删除,并将其字符串化并返回,去重
  • 如果 pfx 是重复的会发生什么?是否应该省略其整个父集?
  • 我想过使用正则表达式,但我认为会有更简单的方法来做到这一点。此外,我认为这可能比其他方式需要更多的逻辑
  • 如果 pfx 是重复的,则应该发出整个集合。所以在上面的例子中:
     { "pfx": "000004", "mask": 24, "desc": "Let's fake this is a repeat" } 
     应该省略
                    
                  
                    
                            
                
  • 澄清一下,您是从 Python 后端提供这些 .js 文件吗?这些数据没有通过 AJAX 作为原始 JSON 发送并且被硬编码到文件中,但足够动态以至于脚本需要对其进行重复数据删除,这是有原因的吗?看起来可能是x-y problem

标签: javascript python arrays duplicates unique


【解决方案1】:

由于结构没有嵌套,可以用正则表达式匹配数组,然后用JSON解析,在Python中用filter去除重复对象,然后用去重的JSON字符串替换。

使用数组字面量语法([])而不是 new Array 来保持简洁(最好不要使用 new Array):

import re
import json
str = '''
var oui = [{
    "pfx": "000000",
    "mask": 24,
    "desc": "00:00:00   Officially Xerox, but 0:0:0:0:0:0 is more common"
},{
    "pfx": "000001",
    "mask": 24,
    "desc": "Xerox  Xerox Corporation"
},{
    "pfx": "000002",
    "mask": 24,
    "desc": "Xerox  Xerox Corporation"
},{
    "pfx": "000003",
    "mask": 24,
    "desc": "Xerox  Xerox Corporation"
},{
    "pfx": "000004",
    "mask": 24,
    "desc": "Xerox  Xerox Corporation"
},{
    "pfx": "000004",
    "mask": 24,
    "desc": "Let's pretend this is a repeat"
   }];
'''

def dedupe(match):
   jsonStr = match.group()
   list = json.loads(jsonStr)
   seenPfxs = set()
   def notDupe(obj):
        thisPfx = obj['pfx']
        if thisPfx in seenPfxs:
            return False
        seenPfxs.add(thisPfx)
        return True
   return json.dumps([obj for obj in list if notDupe(obj)])

dedupedStr = re.sub(r'(?s)\[[^\]]+\](?=;)', dedupe, str)
print(dedupedStr)

输出:

var oui = [{"pfx": "000000", "mask": 24, "desc": "00:00:00   Officially Xerox, but 0:0:0:0:0:0 is more common"}, {"pfx": "000001", "mask": 24, "desc": "Xerox  Xerox Corporation"}, {"pfx": "000002", "mask": 24, "desc": "Xerox  Xerox Corporation"}, {"pfx": "000003", "mask": 24, "desc": "Xerox  Xerox Corporation"}, {"pfx": "000004", "mask": 24, "desc": "Xerox  Xerox Corporation"}];

如果可能,您可能会考虑将数据存储在单独的标签中,而不是使用内联 Javascript - 它会更易于维护。例如,在您的 HTML 中,而不是

var oui = [{
    "pfx": "000000",
    "mask": 24,
    "desc": "00:00:00   Officially Xerox, but 0:0:0:0:0:0 is more common"
},{

考虑类似

var oui = JSON.parse(document.querySelector('[data-oui').textContent);
console.log(oui);
<script data-oui type="application/json">[{
    "pfx": "000000",
    "mask": 24,
    "desc": "00:00:00   Officially Xerox, but 0:0:0:0:0:0 is more common"
}]</script>

那么您不必动态更改 Javascript,只需 &lt;script data-oui type="application/json"&gt; 标记即可。

【讨论】:

  • 很棒的答案!非常感谢!所以最初我将New Array 放在一个单独的 JS 文件中,而不是使用脚本标签内联 HTML。我应该把它内联吗?另外,您介意解释一下为什么我不应该使用New Array 语法吗?
  • 问题是从服务器获取动态数据到客户端。由你决定。与其他主要方法(网络请求或单独的 Javascript 文件)相比,内联 Javascript 可能更难使用内联 Javascript 意味着 (1) 没有缓存问题(客户端不会收到过时的数据,虽然这是可以修复的)(2)不需要额外的网络 ping,使页面能够更快地处理数据,这是一个明显的小优势。
猜你喜欢
  • 2012-12-06
  • 2013-08-03
  • 2021-07-20
  • 2021-08-15
  • 2015-08-19
  • 2011-12-02
  • 1970-01-01
  • 2023-02-21
  • 2012-10-04
相关资源
最近更新 更多