我正在练习并尝试编写递归数组展平函数。代码在这里:
if (item <= 10)
{
money += 25;
$('#money').html(money);
}
else if (item > 10 && item <= 20)
{
money += 50;
$('#money').html(money);
}
问题是,如果我在那里传递一个数组或嵌套数组,我会得到&#34;超过最大调用堆栈大小&#34;错误。我做错了什么?
答案 0 :(得分:20)
问题是你如何传递数组的处理,如果值是一个数组,那么你一直在调用它导致无限循环
barButtonItem
演示:Fiddle
这是一个更现代的版本:
function flatten() {
var flat = [];
for (var i = 0; i < arguments.length; i++) {
if (arguments[i] instanceof Array) {
flat.push.apply(flat, flatten.apply(this, arguments[i]));
} else {
flat.push(arguments[i]);
}
}
return flat;
}
答案 1 :(得分:3)
[...arr.toString().split(",")]
使用toString()
的{{1}}方法。使用扩展运算符Object
制作一个字符串数组,并用(...)
分割它。
示例:
","
答案 2 :(得分:3)
Haskellesque方法......
function flatArray([x,...xs]){
return x !== undefined ? [...Array.isArray(x) ? flatArray(x) : [x],...flatArray(xs)]
: [];
}
var na = [[1,2],[3,[4,5]],[6,7,[[[8],9]]],10];
fa = flatArray(na);
console.log(fa);
答案 3 :(得分:2)
您的代码缺少else语句,并且递归调用不正确(您反复传递相同的数组而不是传递其项目。)
您的功能可以这样写:
if (long.TryParse(mystringnumber,null))
{
dosomething();
}
答案 4 :(得分:2)
如果你假设你的第一个参数是一个数组,那么你可以很简单。
function flatten(a) {
return a.reduce((flat, i) => {
if (Array.isArray(i)) {
return flat.concat(flatten(i));
}
return flat.concat(i);
}, []);
}
如果您确实想要展平多个数组,只需在传递之前将它们连接起来。
答案 5 :(得分:2)
如果项目是数组,我们只需将所有剩余项目添加到此数组
function flatten(array, result) {
if (array.length === 0) {
return result
}
var head = array[0]
var rest = array.slice(1)
if (Array.isArray(head)) {
return flatten(head.concat(rest), result)
}
result.push(head)
return flatten(rest, result)
}
console.log(flatten([], []))
console.log(flatten([1], []))
console.log(flatten([1,2,3], []))
console.log(flatten([1,2,[3,4]], []))
console.log(flatten([1,2,[3,[4,5,6]]], []))
console.log(flatten([[1,2,3],[4,5,6]], []))
console.log(flatten([[1,2,3],[[4,5],6,7]], []))
console.log(flatten([[1,2,3],[[4,5],6,[7,8,9]]], []))
答案 6 :(得分:1)
如果有人在寻找扁平的对象数组(例如tree
),那么这里是代码:
function flatten(items) {
const flat = [];
items.forEach(item => {
flat.push(item)
if (Array.isArray(item.children) && item.children.length > 0) {
flat.push(...flatten(item.children));
delete item.children
}
delete item.children
});
return flat;
}
var test = [
{children: [
{children: [], title: '2'}
],
title: '1'},
{children: [
{children: [], title: '4'},
{children: [], title: '5'}
],
title: '3'}
]
console.log(flatten(test))
&#13;
答案 7 :(得分:1)
flat()
:const array = [1, 1, [2, 2], [[3, [4], 3], 2]]
// All layers
array.flat(Infinity) // [1, 1, 2, 2, 3, 4, 3, 2]
// Varying depths
array.flat() // [1, 1, 2, 2, Array(3), 2]
array.flat(2) // [1, 1, 2, 2, 3, Array(1), 3, 2]
array.flat().flat() // [1, 1, 2, 2, 3, Array(1), 3, 2]
array.flat(3) // [1, 1, 2, 2, 3, 4, 3, 2]
array.flat().flat().flat() // [1, 1, 2, 2, 3, 4, 3, 2]
Can I Use-2019年11月为84%
答案 8 :(得分:1)
这是我的实用方法:
const deepFlatten = (array => (array, start = []) => array.reduce((acc, curr) => {
return Array.isArray(curr) ? deepFlatten(curr, acc) : [...acc, curr];
}, start))();
console.log(deepFlatten([[1,2,[3, 4, [5, [6]]]],7]));
答案 9 :(得分:0)
现代而不是跨浏览器
function flatten(arr) {
return arr.flatMap(el => {
if(Array.isArray(el)) {
return flatten(el)
} else {
return el;
}
})
}
答案 10 :(得分:0)
有几种方法可以做到这一点:
使用 flat 方法和 Infinity 关键字:
const flattened = arr.flat(Infinity);
您可以使用 reduce 和 concat 方法来展平任何数组,如下所示:
function flatten(arr) { return arr.reduce((acc, cur) => acc.concat(Array.isArray(cur) ? flatten(cur) : cur), []); };
阅读更多信息: https://www.techiedelight.com/recursively-flatten-nested-array-javascript/
答案 11 :(得分:0)
我已经在 stackoverflow 中的 this page 上发布了我的数组展平的递归版本。
答案 12 :(得分:0)
下面的函数对数组进行扁平化处理,并保留每个项目的类型,而不是将它们更改为字符串。如果您需要扁平化不只包含数字之类的数组,这将非常有用。它可以扁平化任何类型的数组,没有副作用。
function flatten(arr) {
for (let i = 0; i < arr.length; i++) {
arr = arr.reduce((a, b) => a.concat(b),[])
}
return arr
}
console.log(flatten([1, 2, [3, [[4]]]]));
console.log(flatten([[], {}, ['A', [[4]]]]));
答案 13 :(得分:0)
我认为问题在于您使用 arguments
的方式。
既然你说传递嵌套数组时,会导致“最大调用堆栈大小超出”错误。
因为 arguments[0]
是指向您传递给 flatten
函数的第一个参数的引用。例如:
flatten([1,[2,[3]]]) // arguments[0] will always represents `[1,[2,[3]]]`
因此,您的代码最终会使用相同的参数一次又一次地调用 flatten
。
要解决这个问题,我认为最好使用named arguments
,而不是使用arguments
,后者本质上不是“真正的数组”。
答案 14 :(得分:0)
我希望你能有所不同。一种结合了递归和“for循环”/高阶函数。我想在没有 for 循环或高阶函数的情况下回答。
再次检查数组的第一个元素是否为数组。如果是,请递归直到到达最里面的数组。然后推到结果。我希望我以纯粹的递归方式接近它。
function flatten(arr, result = []) {
if(!arr.length) return result;
(Array.isArray(arr[0])) ? flatten(arr[0], result): result.push(arr[0]);
return flatten(arr.slice(1),result)
}
答案 15 :(得分:0)
在JavaScript中扁平化数组的递归方法如下。
function flatten(array) {
let flatArray = [];
for (let i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) {
flatArray.push(...flatten(array[i]));
} else {
flatArray.push(array[i]);
}
}
return flatArray;
}
let array = [[1, 2, 3], [[4, 5], 6, [7, 8, 9]]];
console.log(flatten(array));
// Output = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
let array2 = [1, 2, [3, [4, 5, 6]]];
console.log(flatten(array2));
// Output = [ 1, 2, 3, 4, 5, 6 ]
答案 16 :(得分:0)
这应该有效
function flatten() {
var flat = [
];
for (var i = 0; i < arguments.length; i++) {
flat = flat.concat(arguments[i]);
}
var removeIndex = [
];
for (var i = flat.length - 1; i >= 0; i--) {
if (flat[i] instanceof Array) {
flat = flat.concat(flatten(flat[i]));
removeIndex.push(i);
}
}
for (var i = 0; i < removeIndex.length; i++) {
flat.splice(removeIndex - i, 1);
}
return flat;
}
答案 17 :(得分:0)
这是从 absurdum 采取的递归化简实现,它模仿lodash的_.concat()
它可以接受任意数量的数组或非数组参数。数组可以是任意深度。结果输出将是一个单一的平坦值数组。
export const concat = (...arrays) => {
return flatten(arrays, []);
}
function flatten(array, initial = []) {
return array.reduce((acc, curr) => {
if(Array.isArray(curr)) {
acc = flatten(curr, acc);
} else {
acc.push(curr);
}
return acc;
}, initial);
}
它可以接受任意数量的数组或非数组值作为输入。
来源:我是荒诞派的作者
答案 18 :(得分:0)
这是针对此问题的Vanilla JavaScript解决方案
var _items = {'keyOne': 'valueOne', 'keyTwo': 'valueTwo', 'keyThree': ['valueTree', {'keyFour': ['valueFour', 'valueFive']}]};
// another example
// _items = ['valueOne', 'valueTwo', {'keyThree': ['valueTree', {'keyFour': ['valueFour', 'valueFive']}]}];
// another example
/*_items = {"data": [{
"rating": "0",
"title": "The Killing Kind",
"author": "John Connolly",
"type": "Book",
"asin": "0340771224",
"tags": "",
"review": "i still haven't had time to read this one..."
}, {
"rating": "0",
"title": "The Third Secret",
"author": "Steve Berry",
"type": "Book",
"asin": "0340899263",
"tags": "",
"review": "need to find time to read this book"
}]};*/
function flatten() {
var results = [],
arrayFlatten;
arrayFlatten = function arrayFlattenClosure(items) {
var key;
for (key in items) {
if ('object' === typeof items[key]) {
arrayFlatten(items[key]);
} else {
results.push(items[key]);
}
}
};
arrayFlatten(_items);
return results;
}
console.log(flatten());
&#13;
答案 19 :(得分:0)
其他答案已经指出了OP代码故障的根源。编写更多描述性代码,问题实际上归结为“array-detection / -reduce / -concat-recursion”......
(function (Array, Object) {
//"use strict";
var
array_prototype = Array.prototype,
array_prototype_slice = array_prototype.slice,
expose_internal_class = Object.prototype.toString,
isArguments = function (type) {
return !!type && (/^\[object\s+Arguments\]$/).test(expose_internal_class.call(type));
},
isArray = function (type) {
return !!type && (/^\[object\s+Array\]$/).test(expose_internal_class.call(type));
},
array_from = ((typeof Array.from == "function") && Array.from) || function (listAlike) {
return array_prototype_slice.call(listAlike);
},
array_flatten = function flatten (list) {
list = (isArguments(list) && array_from(list)) || list;
if (isArray(list)) {
list = list.reduce(function (collector, elm) {
return collector.concat(flatten(elm));
}, []);
}
return list;
}
;
array_prototype.flatten = function () {
return array_flatten(this);
};
}(Array, Object));
借用其他答案之一的代码作为概念证据......
console.log([
[[[0, 1, 2], [0, 1, 2]], [[0, 1, 2], [0, 1, 2]]],
[[[0, 1, 2], [0, 1, 2]], [[0, 1, 2], [0, 1, 2]]]
].flatten());
//[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ..., ..., ..., 0, 1, 2]
答案 20 :(得分:-1)
你应该为递归添加停止条件。
作为一个例子 如果len(arguments [i])== 0返回