Have an array arr =
有一个数组arr =
[ [1,2] , [5,1], [23,24], [3,4], [22,23], [2,3]]
output needed = [[5,1,2,3,4],[22,23,24]]
tried using concat, reduce methods of array in javascript but could not achieve the desired result - any ideas?
尝试使用concat,在javascript中减少数组的方法,但无法达到预期的结果 - 任何想法?
3 个解决方案
#1
0
I'm going to start by saying the code example and description is not very clear, but I'll take a shot...
我将首先说代码示例和描述不是很清楚,但我会拍一下......
It seems you have 3 requirements:
看来你有3个要求:
- Flatten the original array.
- Filter out duplicates.
- Group values (somehow?) within the flattened array.
展平原始数组。
过滤掉重复的内容。
在展平数组中分组值(以某种方式?)。
The first 2 tasks on the list can be accomplished using reduce, concat, filter and indexOf methods.
列表中的前两个任务可以使用reduce,concat,filter和indexOf方法完成。
var multiArray = [ [1,2] , [5,1], [23,24], [3,4], [22,23], [2,3] ];
var flattened = multiArray.reduce(function (prev, curr) {
return prev.concat(curr);
}, []);
var unique = flattened.filter(function (element, index, array) {
return array.indexOf(element) === index;
});
However, I wont be able to give you an example for that last task until you make it clear how you're hoping to have these values grouped within the flattened array.
但是,在您明确表示希望如何将这些值组合在展平数组中之前,我无法为您提供上一个任务的示例。
I'll update my original answer once clarified.
一旦澄清,我会更新我的原始答案。
#2
0
This is another solution yet i believe i can make it with less code and more functional. I don't enjoy using forEach()
or flags like reduced
much. This one recursively encodes the array items until there is nothing left to encode. Later I will give it another try to make it look more sleek.
这是另一种解决方案,但我相信我可以用更少的代码和更多的功能来实现它。我不喜欢使用forEach()或降低很多的标志。这个递归地对数组项进行编码,直到没有任何东西可以编码。稍后我会再试一次,让它看起来更圆滑。
var rawarr = [[1,2], [5,1], [23,24], [3,4], [22,23], [2,3]],
encodarr = (arr) => {
var reduced = false;
arr.forEach((c,i,a) => {
var sa = a.slice(i+1),
j = sa.findIndex(f => c[0] == f[f.length-1] || c[c.length-1] == f[0]);
arr[i] = !!~j ? c[0] == sa[j][sa[j].length-1] ? (reduced = true, a.splice(i+j+1,1)[0].concat(c.slice(1)))
: (reduced = true, c.slice(0,-1).concat(a.splice(i+j+1,1)[0]))
: c;
return arr;
});
return reduced ? encodarr(arr) : arr;
};
document.write("<pre>" + JSON.stringify(encodarr(rawarr)) + "</pre>");
#3
0
Basically this problem can be solved with more loops and only one array (A) or with an object as reference and only one loop (B).
基本上这个问题可以用更多的循环来解决,只有一个数组(A)或一个对象作为参考,只有一个循环(B)。
A
An in situ proposal with no object, but with more loops. It checks every array with the path information with each other. If a match is found, the two arrays are
一个没有对象的原位提案,但有更多的循环。它使用彼此的路径信息检查每个数组。如果找到匹配,则两个数组是
var data = [[1, 2], [5, 1], [23, 24], [3, 4], [22, 23], [2, 3], [4, 5]],
result = function (data) {
function first(a) { return a[0]; }
function last(a) { return a[a.length - 1]; }
var i = 0, j, t;
outer: while (i < data.length - 1) {
j = i + 1;
while (j < data.length) {
t = data.splice(j, 1)[0];
if (first(data[i]) === last(t)) {
t.pop();
data[i] = t.concat(data[i]);
i = 0;
continue outer;
}
if (last(data[i]) === first(t)) {
t.shift();
data[i] = data[i].concat(t);
i = 0;
continue outer;
}
data.push(t);
j++;
}
i++
}
return data;
}(data);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
B
This is a single loop proposal which takes all parts and appends them if possible. Later all start arrays are returned as result.
这是一个单循环提议,它会获取所有部分并在可能的情况下附加它们。稍后将返回所有启动数组作为结果。
var data = [[1, 2], [5, 1], [23, 24], [3, 4], [22, 23], [2, 3], [4, 5]],
result = function (data) {
var o = { start: {}, end: {} };
data.forEach(function (a) {
var temp;
if (o.end[a[0]]) {
if (o.start[a[1]] && a[0] !== o.start[a[1]][o.start[a[1]].length - 1] && a[1] !== o.end[a[0]][0]) {
temp = o.end[a[0]].concat(o.start[a[1]]);
o.start[temp[0]] = temp;
o.end[temp[temp.length - 1]] = temp;
delete o.start[a[1]];
} else {
o.end[a[1]] = o.end[a[0]];
o.end[a[1]].push(a[1]);
}
delete o.end[a[0]];
return;
}
if (o.start[a[1]]) {
o.start[a[0]] = o.start[a[1]];
o.start[a[0]].unshift(a[0]);
delete o.start[a[1]];
return;
}
temp = a.slice();
o.start[a[0]] = temp;
o.end[a[1]] = temp;
});
return Object.keys(o.start).map(function (k) { return o.start[k]; });
}(data);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
#1
0
I'm going to start by saying the code example and description is not very clear, but I'll take a shot...
我将首先说代码示例和描述不是很清楚,但我会拍一下......
It seems you have 3 requirements:
看来你有3个要求:
- Flatten the original array.
- Filter out duplicates.
- Group values (somehow?) within the flattened array.
展平原始数组。
过滤掉重复的内容。
在展平数组中分组值(以某种方式?)。
The first 2 tasks on the list can be accomplished using reduce, concat, filter and indexOf methods.
列表中的前两个任务可以使用reduce,concat,filter和indexOf方法完成。
var multiArray = [ [1,2] , [5,1], [23,24], [3,4], [22,23], [2,3] ];
var flattened = multiArray.reduce(function (prev, curr) {
return prev.concat(curr);
}, []);
var unique = flattened.filter(function (element, index, array) {
return array.indexOf(element) === index;
});
However, I wont be able to give you an example for that last task until you make it clear how you're hoping to have these values grouped within the flattened array.
但是,在您明确表示希望如何将这些值组合在展平数组中之前,我无法为您提供上一个任务的示例。
I'll update my original answer once clarified.
一旦澄清,我会更新我的原始答案。
#2
0
This is another solution yet i believe i can make it with less code and more functional. I don't enjoy using forEach()
or flags like reduced
much. This one recursively encodes the array items until there is nothing left to encode. Later I will give it another try to make it look more sleek.
这是另一种解决方案,但我相信我可以用更少的代码和更多的功能来实现它。我不喜欢使用forEach()或降低很多的标志。这个递归地对数组项进行编码,直到没有任何东西可以编码。稍后我会再试一次,让它看起来更圆滑。
var rawarr = [[1,2], [5,1], [23,24], [3,4], [22,23], [2,3]],
encodarr = (arr) => {
var reduced = false;
arr.forEach((c,i,a) => {
var sa = a.slice(i+1),
j = sa.findIndex(f => c[0] == f[f.length-1] || c[c.length-1] == f[0]);
arr[i] = !!~j ? c[0] == sa[j][sa[j].length-1] ? (reduced = true, a.splice(i+j+1,1)[0].concat(c.slice(1)))
: (reduced = true, c.slice(0,-1).concat(a.splice(i+j+1,1)[0]))
: c;
return arr;
});
return reduced ? encodarr(arr) : arr;
};
document.write("<pre>" + JSON.stringify(encodarr(rawarr)) + "</pre>");
#3
0
Basically this problem can be solved with more loops and only one array (A) or with an object as reference and only one loop (B).
基本上这个问题可以用更多的循环来解决,只有一个数组(A)或一个对象作为参考,只有一个循环(B)。
A
An in situ proposal with no object, but with more loops. It checks every array with the path information with each other. If a match is found, the two arrays are
一个没有对象的原位提案,但有更多的循环。它使用彼此的路径信息检查每个数组。如果找到匹配,则两个数组是
var data = [[1, 2], [5, 1], [23, 24], [3, 4], [22, 23], [2, 3], [4, 5]],
result = function (data) {
function first(a) { return a[0]; }
function last(a) { return a[a.length - 1]; }
var i = 0, j, t;
outer: while (i < data.length - 1) {
j = i + 1;
while (j < data.length) {
t = data.splice(j, 1)[0];
if (first(data[i]) === last(t)) {
t.pop();
data[i] = t.concat(data[i]);
i = 0;
continue outer;
}
if (last(data[i]) === first(t)) {
t.shift();
data[i] = data[i].concat(t);
i = 0;
continue outer;
}
data.push(t);
j++;
}
i++
}
return data;
}(data);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
B
This is a single loop proposal which takes all parts and appends them if possible. Later all start arrays are returned as result.
这是一个单循环提议,它会获取所有部分并在可能的情况下附加它们。稍后将返回所有启动数组作为结果。
var data = [[1, 2], [5, 1], [23, 24], [3, 4], [22, 23], [2, 3], [4, 5]],
result = function (data) {
var o = { start: {}, end: {} };
data.forEach(function (a) {
var temp;
if (o.end[a[0]]) {
if (o.start[a[1]] && a[0] !== o.start[a[1]][o.start[a[1]].length - 1] && a[1] !== o.end[a[0]][0]) {
temp = o.end[a[0]].concat(o.start[a[1]]);
o.start[temp[0]] = temp;
o.end[temp[temp.length - 1]] = temp;
delete o.start[a[1]];
} else {
o.end[a[1]] = o.end[a[0]];
o.end[a[1]].push(a[1]);
}
delete o.end[a[0]];
return;
}
if (o.start[a[1]]) {
o.start[a[0]] = o.start[a[1]];
o.start[a[0]].unshift(a[0]);
delete o.start[a[1]];
return;
}
temp = a.slice();
o.start[a[0]] = temp;
o.end[a[1]] = temp;
});
return Object.keys(o.start).map(function (k) { return o.start[k]; });
}(data);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');