合并重叠的数据集

Merging overlapping datasets

本文关键字:数据集 重叠 合并      更新时间:2023-09-26

给定多个可能/可能不重叠在一个或多个列上的数据集,我希望动态地将数据集合并在一起。

是否有一个库或代码片段将以这种方式合并数据集?如何使用单个列作为键?

示例:合并两个数据集,使用多个列作为键(BookTitle, Author)

Input, Dataset 1

BookTitle, Author, Publisher
title1, author1, publisher1
title2, author2, publisher2
title3, author3, publisher3

Input, Dataset 2

BookTitle, Author, NumPages
title4, author4, numPages4
title7, author7, numPages7
title5, author5, numPages5
title3, author33, numPages3
title2, author2, numPages2

Output, Munged Dataset

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通常表示空引用。相反,我忽略了它们。访问数组中没有这些字段的对象的字段将导致undefined,这是完全有意义的。

同样,以下是本文代码的限制。您可以编辑它以消除这些限制,使其更健壮。

  1. 这与您在问题中提到的数据格式有关。要使其适用于任意集合,您可以在for-in循环中使用Object.hasOwnProperty()检查是否存在属性,并添加必要的属性,从而导致合并。

http://jsfiddle.net/x5Q5g/

编辑:

哦!顺便说一下,代码是JavaScript,数据格式可以是JSON,只要你使用JSON.parse()JSON.stringify()

Edit:下面的更新消除了上面提到的第一个限制。请注意,您需要显式地传入键以进行比较。

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);
http://jsfiddle.net/s6HqL/

最后一个更新:这里是如何使它接受任意数量的密钥。我忘了您需要多个键支持。对不起!

您需要更改以下内容。

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);
http://jsfiddle.net/s6HqL/3/

最后一段和上面的代码完成了。没有任何推荐信!并且是通用的。可以使用任意数量的键作为参数