ramda.js:使用特定属性从对象数组中获取一组重复项
ramda.js: obtain a set of duplicates from an array of objects using specific properties
给定这个数组,包含 javascript 个对象 (json):
每个对象都有一个b
属性和一个u
属性,
(每个都包含我在本练习中不关心的其他属性)。
[
{ "b": "A", "u": "F", ... },
{ "b": "M", "u": "T", ... },
{ "b": "A", "u": "F", ... },
{ "b": "M", "u": "T", ... },
{ "b": "M", "u": "T", ... },
{ "b": "X", "u": "Y", ... },
{ "b": "X", "u": "G", ... },
]
我想使用 ramda 找到一组所有重复项。
结果应如下所示。
[
{ "b": "A", "u":"F" },
{ "b": "M", "u":"T" }
]
这两个条目有重复项,它们在原始列表中分别重复了 2 次和 3 次。
编辑
我找到了一个使用 underscore 的解决方案,它保留了原始数组元素,并将它们完美地拆分为单个元素和重复元素。我更喜欢 ramda.js,并且下划线不只是给出一组重复项 - 根据问题,所以我将问题悬而未决,直到有人可以使用 ramda 回答。我将继续使用下划线,直到问题得到解答。
我有一个 repl 可以找到唯一值...作为开始...
不是 Ramda JS 专家,但我认为以下内容应该有效:
var p = [
{ "b": "A", "u": "F" },
{ "b": "A", "u": "F" },
{ "b": "A", "u": "F" },
{ "b": "A", "u": "F" },
{ "b": "A", "u": "F" },
{ "b": "M", "u": "T" }
];
var dupl = n => n > 1;
R.compose(
R.map(JSON.parse),
R.keys,
R.filter(dupl),
R.countBy(String),
R.map(JSON.stringify)
)(p)
如果有,请告诉我。
如果你不关心多次循环你的数据,你可以这样:
- 创建仅包含相关道具的部分副本,使用
pick
(您自己的想法)
- 使用
groupBy
和 hash
函数对相似的对象进行分组。 (Alternatively: sort
先用 groupWith(equals)
)
- 使用
values
获取分组数组
- 使用
filter
过滤掉只有 1 个项目的数组(那些没有被欺骗...)
- 使用
map(head)
映射结果和 return 每个数组的第一个元素
在代码中:
const containsMoreThanOne = compose(lt(1), length);
const hash = JSON.stringify; // Naive.. watch out for key-order!
const getDups = pipe(
map(pick(["b", "u"])),
groupBy(hash),
values,
filter(containsMoreThanOne),
map(head)
);
getDups(data);
Ramda REPL 中的工作演示。
一种更混合的方法是将所有这些逻辑压缩在一个减速器中,但对我来说它看起来有点乱...
const clean = pick(["b", "u"]);
const hash = JSON.stringify;
const dupReducer = hash => (acc, o) => {
const h = hash(o);
// Mutate internal state
acc.done[h] = (acc.done[h] || 0) + 1;
if (acc.done[h] === 2) acc.result.push(o);
return acc;
};
const getDups = (clean, hash, data) =>
reduce(dupReducer(hash), { result: [], done: { } }, map(clean, data)).result;
getDups(clean, hash, data);
这似乎过于复杂并且不太可能是高性能的,但一种选择是:
const foo = pipe(
project(['b', 'u']),
reduce(
({results, foundOnce}, item) => contains(item, results)
? {results, foundOnce}
: contains(item, foundOnce)
? {results: append(item, results), foundOnce}
: {results, foundOnce: append(item, foundOnce)},
{results: [], foundOnce: []}
),
prop('results')
)
foo(xs); //=> [{b: 'A', u: 'F'}, {b: 'M', u: 'T'}]
也许这个版本更容易理解,但需要额外迭代数据:
const foo = pipe(
project(['b', 'u']),
reduce(
({results, foundOnce}, item) => contains(item, foundOnce)
? {results: append(item, results), foundOnce}
: {results, foundOnce: append(item, foundOnce)},
{results: [], foundOnce: []}
),
prop('results'),
uniq
)
const arr = [];
const duplicates = [];
const values1 = [
{ b: 'A', u: 'F', a: 'q' },
{ b: 'M', u: 'T', a: 'q' },
{ b: 'A', u: 'F', a: 'q' },
{ b: 'M', u: 'T', a: 'q' },
{ b: 'M', u: 'T', a: 'q' },
{ b: 'X', u: 'Y', a: 'q' },
{ b: 'X', u: 'G', a: 'q' },
];
values1.forEach(eachValue => {
arr.push(values(pick(['b', 'u'], eachValue)));
});
arr.forEach(fish => {
if ( indexOf(fish, arr) !== lastIndexOf(fish, arr) ) {
duplicates.push(zipObj(['b', 'u'], fish));
}
});
[blog]: https://ramdafunctionsexamples.com/ "click here for updates"
<https://ramdafunctionsexamples.com/>?
给定这个数组,包含 javascript 个对象 (json):
每个对象都有一个b
属性和一个u
属性,
(每个都包含我在本练习中不关心的其他属性)。
[
{ "b": "A", "u": "F", ... },
{ "b": "M", "u": "T", ... },
{ "b": "A", "u": "F", ... },
{ "b": "M", "u": "T", ... },
{ "b": "M", "u": "T", ... },
{ "b": "X", "u": "Y", ... },
{ "b": "X", "u": "G", ... },
]
我想使用 ramda 找到一组所有重复项。 结果应如下所示。
[
{ "b": "A", "u":"F" },
{ "b": "M", "u":"T" }
]
这两个条目有重复项,它们在原始列表中分别重复了 2 次和 3 次。
编辑
我找到了一个使用 underscore 的解决方案,它保留了原始数组元素,并将它们完美地拆分为单个元素和重复元素。我更喜欢 ramda.js,并且下划线不只是给出一组重复项 - 根据问题,所以我将问题悬而未决,直到有人可以使用 ramda 回答。我将继续使用下划线,直到问题得到解答。
我有一个 repl 可以找到唯一值...作为开始...
不是 Ramda JS 专家,但我认为以下内容应该有效:
var p = [
{ "b": "A", "u": "F" },
{ "b": "A", "u": "F" },
{ "b": "A", "u": "F" },
{ "b": "A", "u": "F" },
{ "b": "A", "u": "F" },
{ "b": "M", "u": "T" }
];
var dupl = n => n > 1;
R.compose(
R.map(JSON.parse),
R.keys,
R.filter(dupl),
R.countBy(String),
R.map(JSON.stringify)
)(p)
如果有,请告诉我。
如果你不关心多次循环你的数据,你可以这样:
- 创建仅包含相关道具的部分副本,使用
pick
(您自己的想法) - 使用
groupBy
和hash
函数对相似的对象进行分组。 (Alternatively:sort
先用groupWith(equals)
) - 使用
values
获取分组数组
- 使用
filter
过滤掉只有 1 个项目的数组(那些没有被欺骗...)
- 使用
map(head)
映射结果和 return 每个数组的第一个元素
在代码中:
const containsMoreThanOne = compose(lt(1), length);
const hash = JSON.stringify; // Naive.. watch out for key-order!
const getDups = pipe(
map(pick(["b", "u"])),
groupBy(hash),
values,
filter(containsMoreThanOne),
map(head)
);
getDups(data);
Ramda REPL 中的工作演示。
一种更混合的方法是将所有这些逻辑压缩在一个减速器中,但对我来说它看起来有点乱...
const clean = pick(["b", "u"]);
const hash = JSON.stringify;
const dupReducer = hash => (acc, o) => {
const h = hash(o);
// Mutate internal state
acc.done[h] = (acc.done[h] || 0) + 1;
if (acc.done[h] === 2) acc.result.push(o);
return acc;
};
const getDups = (clean, hash, data) =>
reduce(dupReducer(hash), { result: [], done: { } }, map(clean, data)).result;
getDups(clean, hash, data);
这似乎过于复杂并且不太可能是高性能的,但一种选择是:
const foo = pipe(
project(['b', 'u']),
reduce(
({results, foundOnce}, item) => contains(item, results)
? {results, foundOnce}
: contains(item, foundOnce)
? {results: append(item, results), foundOnce}
: {results, foundOnce: append(item, foundOnce)},
{results: [], foundOnce: []}
),
prop('results')
)
foo(xs); //=> [{b: 'A', u: 'F'}, {b: 'M', u: 'T'}]
也许这个版本更容易理解,但需要额外迭代数据:
const foo = pipe(
project(['b', 'u']),
reduce(
({results, foundOnce}, item) => contains(item, foundOnce)
? {results: append(item, results), foundOnce}
: {results, foundOnce: append(item, foundOnce)},
{results: [], foundOnce: []}
),
prop('results'),
uniq
)
const arr = [];
const duplicates = [];
const values1 = [
{ b: 'A', u: 'F', a: 'q' },
{ b: 'M', u: 'T', a: 'q' },
{ b: 'A', u: 'F', a: 'q' },
{ b: 'M', u: 'T', a: 'q' },
{ b: 'M', u: 'T', a: 'q' },
{ b: 'X', u: 'Y', a: 'q' },
{ b: 'X', u: 'G', a: 'q' },
];
values1.forEach(eachValue => {
arr.push(values(pick(['b', 'u'], eachValue)));
});
arr.forEach(fish => {
if ( indexOf(fish, arr) !== lastIndexOf(fish, arr) ) {
duplicates.push(zipObj(['b', 'u'], fish));
}
});
[blog]: https://ramdafunctionsexamples.com/ "click here for updates"
<https://ramdafunctionsexamples.com/>?