鉴于多个数据集可能/可能不重叠在一个或多列上,我希望将数据集动态合并在一起。
是否有库或代码片段可以以这种方式合并数据集?仅使用单个列作为键来执行此操作怎么样?
示例:使用多列作为键(BookTitle、Author)合并两个数据集
输入,数据集 1
BookTitle, Author, Publisher
title1, author1, publisher1
title2, author2, publisher2
title3, author3, publisher3
输入,数据集 2
BookTitle, Author, NumPages
title4, author4, numPages4
title7, author7, numPages7
title5, author5, numPages5
title3, author33, numPages3
title2, author2, numPages2
输出,Munged 数据集
BookTitle, Author, Publisher, NumPages
title1, author1, publisher1, _null_
title2, author2, publisher2, numPages2
title3, author3, publisher3, _null_
title4, author4, _null_, numPages4
title5, author5, _null_, numPages5
title7, author7, _null_, numPages7
title3, author33, _null_, numPages3
我做了一些研究,但没有立即产生有用的结果(主要是关于同一结构中 JSON 对象的一次性合并(即附加数据,而不是合并不同的数据集))。
我正在寻找 Java/JavaScript,使用 JSON/XML/CSV 数据(按优先顺序),但我会接受其他语言,假设这些算法可以移植。
我还将考虑接受仅在单个列上完成此操作的示例。
最佳答案
嗯,我不会真的为如此简单的东西寻找一个库。相反,请尝试自己构建解决方案。
您可以首先JSON.parse()
任何字符串将它们转换为对象。然后,您可以将这两个对象传递到一个如下所示的函数中。
function mergeSets(first, second) {
var result = first;
second.forEach(function (item, index, array) {
var resultIndex = contains(result, item);
if (resultIndex === -1) {
result.push(item);
} else {
result[resultIndex].numPages = item.numPages;
}
});
return result;
}
请注意,mergeSets()
调用 contains()
,其本质如下。
function contains(set, object) {
var solution = -1;
set.forEach(function (item, index, array) {
if (item.bookTitle == object.bookTitle && item.author == object.author) {
solution = index;
}
});
return solution;
}
正如您所看到的,这确实并不难。抱歉有些变量名。这是匆忙写的。另外,您在结果集的示例中提到,您希望将不可用的字段显示为 null
,这是不合适的,因为 null
通常表示空引用。相反,我忽略了他们。访问数组中没有这些字段的对象上的这些字段将导致未定义
,这是完全合理的。
此外,以下是 fiddle 中代码的限制。您可以对其进行编辑以缓解这些限制并使其更加强大。
它与您在问题中提到的数据格式有关。要使其适用于任意集合,您可以在 for-in 循环中使用
Object.hasOwnProperty()
检查属性是否存在,并添加必要的属性以进行合并。它无论如何都不处理集合内的重复项。
编辑:哦!顺便说一句,代码是 JavaScript,数据格式可以是 JSON,前提是您使用 JSON.parse()
和 JSON.stringify()
。
编辑:以下更新消除了上述第一个限制。请注意,您需要显式地传入要进行比较的 key 。
function contains(set, object, key) {
var solution = -1;
set.forEach(function (item, index, array) {
if (item[key] === object[key]) {
solution = index;
}
});
return solution;
}
function mergeSets(first, second, key) {
var result = first;
second.forEach(function (item, index, array) {
var resultIndex = contains(result, item, key);
if (resultIndex === -1) {
result.push(item);
} else {
result[resultIndex].numPages = item.numPages;
for (var property in item) {
if (item.hasOwnProperty(property)) {
if (!result[resultIndex].hasOwnProperty(property)) {
result[resultIndex].property = item.property;
}
}
}
}
});
return result;
}
var solution = mergeSets(firstSet, secondSet, "bookTitle");
console.log(solution);
最后一个更新:以下是如何让它接受任意数量的 key 。我忘记了你需要多个关键支持。抱歉!
您需要更改以下内容。
function contains(set, object, keys) {
var solution = -1;
set.forEach(function (item, index, array) {
var selfItem = item;
var allKeys = keys.every(function (item, index, array) {
if (selfItem[item] === object[item]) {
return true;
}
});
if (allKeys) {
solution = index;
}
});
return solution;
}
function mergeSets(first, second) {
var result = first;
var keys = Array.prototype.slice.call(arguments, 2);
second.forEach(function (item, index, array) {
var resultIndex = contains(result, item, keys);
if (resultIndex === -1) {
result.push(item);
} else {
for (var property in item) {
if (item.hasOwnProperty(property)) {
if (!result[resultIndex].hasOwnProperty(property)) {
var hello = result[resultIndex];
hello[property] = item[property];
}
}
}
}
});
return result;
}
var solution = mergeSets(firstSet, secondSet, "bookTitle", "author");
console.log(solution);
最后一个 fiddle 和上面的代码已经完成。没有任何引用资料!并且是通用的。可以使用任意数量的键作为参数。
关于javascript - 合并重叠数据集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24968893/