我试图找到两个数组之间的深层差异,如下面的
var arr = [5,4,6,7,8,9]; var against = [1,2,4,5,6];
那么结果应该是
appended = [7, 8, 9], prepended = [], removed = [1, 2]
我的逻辑用完了,这就是我试过的
var prepend = [];
var append = [];
var removed = [];
var len = against.length;
while (len--) {
var itm = listSplit[len];
if (arr.indexOf(itm) === -1) {
removed.push(len);
} else if (itm < arr[0]) {
// ??
}
}
我如何找到这些值。给我一些关于逻辑的想法,找到this。
答案 0 :(得分:2)
其中一个解决方案可能是:
var arr = [7,8,9,5,4,6];
var against = [1,2,4,5,6];
// make a copy of the original array as appended
var appended = arr;
var removed =[];
var prepended =[];
for(var i=0;i<against.length;i++)
{
//if the element is not present in the original array, add it to removed.
if(appended.indexOf(against[i]) == -1)
{
removed.push(against[i]);
}
else
{
//if it is already present, it was not appended, nor prepended,
//remove it from appended.
appended.splice(appended.indexOf(against[i]),1);
}
}
// one more loop to seperate the prepended from the appended values.
for(var j=0;j<appended.length;j++)
{
if(appended[j] < against[against.length-1])
{
prepended.push(appended.splice(j,1));
j--;
}
}
附加数组中的最终值将是附加的数组,并且删除后的数组将是删除的数组。保留的那些将是前置的。
答案 1 :(得分:2)
不幸的答案:这是不可能的。
这是不可能的,因为我们没有更改日志&#34;关于阵列发生什么事情以使其进入特定状态。
例如,考虑以下数组:
var original = [2, 2, 2];
var modified1 = original.concat(2);
var modified2 = [2].concat(original);
var modified3 = modified2.slice(1);
这当然是一个极端的例子,但在最终状态中,modified1
与modified2
具有相同的内容(尽管采用不同的路径到达那里),并且可能更糟,{{1实际上与modified3
具有相同的值,尽管在此期间已经进行了大幅修改。
结论:如果没有关于可以对数组进行哪些修改的非常严格的规则以及以哪种顺序进行修改,就不可能像特定的那样如前所述,附加或删除的内容。
然而,总是所做的是提供差异。差异在这种情况下很有用,因为他们不关心变化是如何发生的;他们只关心最终的差异究竟是什么。但请记住,您仍需要定义diff的工作方式。也就是说,给定以下数组:
original
...你会将其定义为两个变化吗?
var array1 = [1, 2, 3, 4, 5];
var array = [2, 3, 4, 5, 6];
1
...或五个更改(因为每个索引的值不同)?如果你只说两个,那么:
6
完全相同的修改(删除一个前导var array1 = [1, 1];
var array = [1, 6];
,添加一个尾随1
),但在这种情况下,它看起来更像是一次更改:
6
更改为1
。所以是的,这是其中之一&#34;通过报复其他一些问题回答问题&#34;答案,但你需要在这里明确定义你需要的东西。目前看,有不止一些含糊不清的案例需要考虑。
答案 2 :(得分:1)
我的回答有点复杂,但能胜任。
var arr = [5,4,6,7,8,9,3];
var against = [1,2,4,5,6];
var prepend = [];
var append = [];
var removed = [];
for(i=0;i<arr.length;i++){
for(j=0;j<against.length;j++){
if(arr[i]==against[j])
break;
else if(j==against.length)
append.push(arr[i]);
else if((parseInt(against.toString().replace(/,/g,"").indexOf(arr[i]))!=-1)!=true
&& arr[i]<against[against.length-1]
&& (parseInt(prepend.toString().replace(/,/g,"").indexOf(arr[i]))!=-1)!=true)
prepend.push(arr[i]);
else if(parseInt(removed.toString().replace(/,/g,"").indexOf(against[j]))==-1
&& (parseInt(arr.toString().replace(/,/g,"").indexOf(against[j]))!=-1)!=true)
removed.push(against[j]);
else if(parseInt(against.toString().replace(/,/g,"").indexOf(arr[i]))==-1
&& (parseInt(append.toString().replace(/,/g,"").indexOf(arr[i]))!=-1)!=true
&& (parseInt(prepend.toString().replace(/,/g,"").indexOf(arr[i]))!=-1)!=true)
append.push(arr[i]);
}
}
//testing
console.log("Appended = [" + append.toString() + "]");
console.log("Prepended = [" + prepend.toString() + "]");
console.log("Removed = [" + removed.toString() + "]");
答案 3 :(得分:1)
不确定您是想在VanillaJS中使用结果还是使用其他库。使用Underscore.JS或Lodash.JS,您可以执行以下操作:
_.difference(against, arr) // [1,2] aka removed
_.difference(arr, against) // [7,8,9] aka appended
我并没有真正理解您的意思,因为您的示例不包含此信息。是原始arr之前/之后添加的附加数字的区别吗?你需要填补哪些空白?也许你可以提出一些额外的例子。
如果是简单的pre / app nding,你将搜索最小数字,并将append()结果除以该结果。之前的一切=前置,之后=附加。这可以通过以下方法实现:
// Lets say the difference is [1,7,8,9] and min number of against = 2
_.filter(_.difference(arr, against), function(n) { return n < _.min(against) }) // [1]
_.filter(_.difference(arr, against), function(n) { return n > _.min(against) }) // [7,8,9]
答案 4 :(得分:1)
这很有效。
// 1. inputs are sorted arrays. example [ -7, -6, 0, 4, 5, 6, 7, 8, 9 ] [ 1, 2, 4, 5, 6 ]
// 2. differences are contiguous. If not, question the question!
function diff(now, was) {
var results = {prepended:[], appended:[], removed:[]}
// prepended is -7 thru 0. Its realm is the now array
for ( var inow = 0; inow < now.length; ++inow ) {
if ( now[inow] >= was[0] ) {
break;
}
}
// inow points to first element in now that is part of was
results.prepended = now.slice(0,inow);
// removed is 1 thru 2. Its realm is the was array
var ref = now[inow];
for ( var iwas = 0; iwas < was.length; ++iwas ) {
if ( was[iwas] == ref ) {
break;
}
}
// iwas points to the first element in was that is present in now
results.removed = was.slice(0,iwas);
// appended is 7 thru 9. Its realm is now
var ref = was[was.length-1];
var i = now.indexOf(ref);
if ( i !== -1 ) {
while ( ++i < now.length && now[i] == ref ) {}
results.appended = now.slice(i);
}
console.log("> orig", now, was);
console.log("> results", results);
}
console.log("\nempties");
diff([], []);
console.log("\nsample");
diff([-7,-6,0,4,5,6,7,8,9], [1,2,4,5,6]);
console.log("\nsample2");
diff([-7,-6,0,4,5,6,6,7,8,9], [1,2,4,5,6]);
console.log("\nonly prepended/removed");
diff([-7,-6,0,4,5,6], [1,2,4,5,6]);
console.log("\nonly removed");
diff([4,5,6], [1,2,2,4,4,5,6]);
在节点
中运行时的输出C:\node>node pa.js
empties
> orig [] []
> results { prepended: [], appended: [], removed: [] }
sample
> orig [ -7, -6, 0, 4, 5, 6, 7, 8, 9 ] [ 1, 2, 4, 5, 6 ]
> results { prepended: [ -7, -6, 0 ],
appended: [ 7, 8, 9 ],
removed: [ 1, 2 ] }
sample2
> orig [ -7, -6, 0, 4, 5, 6, 6, 7, 8, 9 ] [ 1, 2, 4, 5, 6 ]
> results { prepended: [ -7, -6, 0 ],
appended: [ 7, 8, 9 ],
removed: [ 1, 2 ] }
only prepended/removed
> orig [ -7, -6, 0, 4, 5, 6 ] [ 1, 2, 4, 5, 6 ]
> results { prepended: [ -7, -6, 0 ], appended: [], removed: [ 1, 2 ] }
only removed
> orig [ 4, 5, 6 ] [ 1, 2, 2, 4, 4, 5, 6 ]
> results { prepended: [], appended: [], removed: [ 1, 2, 2 ] }
答案 5 :(得分:0)
您只能使用过滤功能来实现答案。
这是你想要的
var appended = arr.filter(function (elm) {
return against.filter(function (elm2) {
return elm2 == elm
}).length == 0;
})
以上代码用于附加数组。
var removed = against.filter(function (elm) {
return elm < arr[0]
});
以上代码用于删除数组
var prepended = arr.filter(function (elm) {
return elm < against[0]
});
以上代码用于前置数组。