减少 JavaScript 对象中的重复项
我有一个像这样的对象:
{
a : 'foo',
b : 'bar',
c : 'foo',
d : 'baz',
e : 'bar'
}
我想减少重复项,例如:
{
ac : 'foo',
be : 'bar',
d : 'baz'
}
有什么好的方法可以做到这一点?
一些警告:
- 只会有少量的配对。 (目前有 7 个;我可以想象它会增加到 20 个。)
- 初始属性名称将仅是单个字符,如示例中所示
- 。值可能会达到数百个字符。
- 速度和代码长度都非常重要,但考虑到行数较少,代码清晰度可能仍然是最重要的。
I've got an object like:
{
a : 'foo',
b : 'bar',
c : 'foo',
d : 'baz',
e : 'bar'
}
I want to reduce the duplicates like:
{
ac : 'foo',
be : 'bar',
d : 'baz'
}
What's a good way to do that?
A few caveats:
- There will only ever be a small number of pairs. (Currently there are 7; I could imagine it going up to, say, 20.)
- The initial property names will only ever be a single character, like in the example
- The values could potentially run to several hundred characters.
- both speed and code-length are highly important, but given the small number of rows, code clarity is probably still most important.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
用作:
Use as:
这是我能得到的最短的:
解释:
obj
中的每个项目,并生成一个新对象newObj
>。newObj
中搜索相同的值。 - 结果是j
,如果找到则为属性名称,如果未找到则为空字符串。j
值。newObj
中找到的属性(如果有),以防止构造重复项。诚然,在循环内设置
j = ""
效率很低。这可以很容易地替换为最初设置为""
的第二个变量,仅在找到匹配时设置为j
。不过,我决定追求简单。This is the shortest I could get it:
Explanation:
obj
, and produces a new object,newObj
.newObj
for the same value. - The result isj
, either the name of the property if found, or an empty string if not.j
.newObj
if there was one, to prevent duplicates being constructed.Admittedly, setting
j = ""
within the loop is inefficient. This can easily be replaced with a second variable set to""
initially, andj
only if a match is found. I decided to go for simplicity though.如果没有更高种类的库,只需循环每对(使用hasOwnProperty)并将键添加/附加到直方图,其中直方图键是对值,直方图值是连接的键。然后反转直方图的键/值。
编辑:如果初始值不是字符串(并且不能可逆映射),则现有的“身份哈希”库可能仍然可以使上述方法发挥作用。
或者,您可以映射为
[[k,v],...]
并排序,然后使用类似于 桶排序(想象它已经排序)以合并输出过程中“相等键”的值。它可能是这样的(虽然代码可能有错误,但该方法是合理的——只要您有办法比较这些值,它也可以将任意对象作为值使用):
Without a higher-kind library just loop each pair (use
hasOwnProperty
) and add/append the key to a histogram where the histogram key is the pair value and the histogram values are the concatenated keys. Then reverse the key/values of the histogram.Edit: If the initial values are not strings (and don't map reversibly) then an existing 'identity hash' library might still enable the above approach to work.
Alternatively, you can map to say,
[[k,v],...]
and sort and then use an approach similar to a bucket sort (imagine it's already sorted) to merge values of "equal keys" in the output pass.It may go like this (while the code may have bugs, the approach is sound -- it will also work with arbitrary objects as values so long as you have a way to compare the values):
遍历对象的每个属性并构造另一个对象,其中键是第一个对象的值,值是键列表(从第一个开始)。然后你返回第二个对象并得出最终结果。
像这样:
现在,如果原始对象的值不是字符串,那么事情会变得更加复杂:只有字符串可以作为 Javascript 对象中的属性键。在这种情况下,您可以寻找更通用的哈希实现。如果您的对象往往非常小(少于 10 个左右的属性),您可以编写 n2 版本,您只需迭代属性,然后对每个属性再次迭代。但是,如果您的对象可能很大并且您必须多次执行此操作,那么这可能是一个坏主意。
Go through each property of the object and construct another object, where the keys are the values of the first, and the values are lists of keys (from the first). Then you go back through that second object and make the final result.
Something like this:
Now, if the values of the original object are not strings, then things get more involved: only strings can be property keys in a Javascript object. You could look around for a more general hash implementation, in that case. If your objects tend to be pretty small (fewer than 10 or so properties) you could write up the n2 version, where you simply iterate over the properties and then iterate again for each one. That would probably be a bad idea however if your objects might be large and you have to perform this operation a lot.
如果我完全不同意,请原谅我,但在我看来,你组合这些的方式,你得到的键和值是错误的。这又如何呢?
应该很容易转换:(
大脑编译;可能有一些错误。)
Forgive me if I'm completely out, but it seems to me that the way you're combining these, you've got the keys and the values the wrong way around. What about this?
Should be easy enough to convert:
(Brain-compiled; there might be a couple of errors.)
从使用字典以翻转方式对标签进行计数的reduce 开始。非常高效的方式,因为它使用内置的字典支持,没有 for 循环等。
返回具有翻转格式的对象:
然后只需翻转格式:
输出:
Start with a reduce that uses a dictionary to count the tags in a flipped way. Very performant way since it uses the built in dictionary support, no for loops etc.
Returns an object with flipped format:
Then just flip the format:
Output: