这是一个我今天遇到的有趣任务,我想不到任何简单的方法来实现所需结果。
假设我们有一个包含以下字段(列)的数据库:A、B、C、D、E、F、G,但是我们不知道这些字段的名称或数量。
我们从该数据库接收一组记录,格式如下:{A:value1, B:value2, ...}。
如果当前记录未设置值,则键也将丢失。这意味着我可以接收{A:value}或{C:value1, D:value2}等有效记录。密钥的顺序总是保持不变。这意味着{D:value,C:value}不是有效记录。
我正在尝试根据返回的记录恢复字段名称并保留密钥的顺序。
例如,我可以接收带有以下密钥的记录:
A、C、D、E、F
D、F、G
A、B、F
从上面的示例中,我应该能够恢复原始的序列,即A、B、C、D、E、F、G。
第一条记录给了我们A、C、D、E和F。
第二个告诉我们G在F之后,所以现在我们有A、C、D、E、F、G。
第三个记录给出B在A之后,所以现在我们有A、B、C、D、E、F、G。
如果确定不了顺序,我们可以使用字母顺序。例如:
A、B
A、C
在上面的示例中,我们无法确定原始顺序是A、B、C还是A、C、B。
有什么想法可以实现这个通用案例吗?
我将使用JavaScript实现此算法,但PHP、C ++或Java也可以。
假设我们有一个包含以下字段(列)的数据库:A、B、C、D、E、F、G,但是我们不知道这些字段的名称或数量。
我们从该数据库接收一组记录,格式如下:{A:value1, B:value2, ...}。
如果当前记录未设置值,则键也将丢失。这意味着我可以接收{A:value}或{C:value1, D:value2}等有效记录。密钥的顺序总是保持不变。这意味着{D:value,C:value}不是有效记录。
我正在尝试根据返回的记录恢复字段名称并保留密钥的顺序。
例如,我可以接收带有以下密钥的记录:
A、C、D、E、F
D、F、G
A、B、F
从上面的示例中,我应该能够恢复原始的序列,即A、B、C、D、E、F、G。
第一条记录给了我们A、C、D、E和F。
第二个告诉我们G在F之后,所以现在我们有A、C、D、E、F、G。
第三个记录给出B在A之后,所以现在我们有A、B、C、D、E、F、G。
如果确定不了顺序,我们可以使用字母顺序。例如:
A、B
A、C
在上面的示例中,我们无法确定原始顺序是A、B、C还是A、C、B。
有什么想法可以实现这个通用案例吗?
我将使用JavaScript实现此算法,但PHP、C ++或Java也可以。
- 创建一个对象,包含所有关系 - 每个数据库记录中的哪个列在哪个列之后。
- 创建每个a-b、b-c之间关系的关系 => a-c(受Floyd-Warshall启发,如果存在,则将每个距离视为1)。
- 创建一个排序函数(比较器),检查两个元素是否可以进行比较。如果不行 - 将使用字母顺序。
- 仅获取唯一的列名,并使用比较器函数对它们进行排序。
您可以在下面找到附加的源代码:
var allComparators = {};
var knownObjects = ['A,C,D,E,F','D,F,G','A,B,F'];
var allFields = knownObjects.join(',').split(',');
for (var i in knownObjects) {
var arr = knownObjects[i].split(',');
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
allComparators[arr[i]+'_'+arr[j]] = 1;
}
}
}
allFields = allFields.filter(function(value, index, self) {
return self.indexOf(value) === index;
});
for (var i in allFields) {
for (var j in allFields) {
for (var k in allFields) {
if (allComparators[allFields[i]+'_'+allFields[j]] && allComparators[allFields[j]+'_'+allFields[k]]) {
allComparators[allFields[i]+'_'+allFields[k]] = 1;
}
}
}
}
allFields.sort(function(a, b) {
if (typeof allComparators[a + '_' + b] != 'undefined') {
return -1;
}
if (typeof allComparators[b + '_' + a] != 'undefined') {
return 1;
}
return a > b;
});
console.log(allFields);