Object转Array函数生成大量空元素问题排查求助
对象转数组出现大量空元素的原因及解决方法
问题重现
编写了一个objectToArray函数用于将对象转换为数组,代码如下:
function objectToArray(obj) { const result = []; for (const [key, value] of Object.entries(obj)) { if (typeof value === 'object' && value !== null) { result[key] = objectToArray(value); } else { result[key] = value; } } return result; }
测试对象:
const obj = { "1129931367": { "id": 10, "amount": 1, "assets": { "appid": 252490, "app_name": "name", "classid": 1129931367, "icon_url": "url", "tradable": 1, "name": "name", "market_name": "market name", "market_hash_name": "market hash name", "sell_listings": 3215, "sell_price": "0.10", "updated_at": "17-Dec-2022" }, "market_tradable_restriction": 7, "market_marketable_restriction": 7, "tags": [ { "category": "category", "internal_name": "internal name", "localized_category_name": "localized category name", "localized_tag_name": "localized tag name" }, { "category": "category", "internal_name": "internal name", "localized_category_name": "localized category name", "localized_tag_name": "localized tag name" } ] } }
转换后输出为(1129931368) [empty × 1129931367, Array(0)],出现大量空元素。
原因分析
问题出在函数逻辑,和测试对象无关:
- 数组的索引是数字类型,当你用字符串类型的大数字
"1129931367"作为数组索引赋值时,JavaScript会自动将其转为数字,然后把数组长度扩展到该数字+1,中间未赋值的位置就会被填充为empty(空槽)。 - 代码错误地将对象的键当作数组索引直接赋值,误解了“对象转数组”的合理逻辑——对象是键值对集合,转数组通常是将每个键值对作为数组元素,而非用键作为数组索引。
解决方法
根据常见的对象转数组需求,提供两种修改方案:
方案1:转换为键值对数组(每个元素是[key, value])
function objectToArray(obj) { const result = []; for (const [key, value] of Object.entries(obj)) { if (Array.isArray(value)) { // 保留原数组结构,递归处理数组内的对象 result.push([key, value.map(item => typeof item === 'object' && item !== null ? objectToArray(item) : item)]); } else if (typeof value === 'object' && value !== null) { // 递归处理嵌套对象 result.push([key, objectToArray(value)]); } else { result.push([key, value]); } } return result; }
转换后会得到层级清晰的键值对数组,不会产生空槽。
方案2:转换为包含键值对象的数组(每个元素是{ key, value })
如果需要更易读的结构,可以改成:
function objectToArray(obj) { const result = []; for (const [key, value] of Object.entries(obj)) { let processedValue; if (Array.isArray(value)) { processedValue = value.map(item => typeof item === 'object' && item !== null ? objectToArray(item) : item); } else if (typeof value === 'object' && value !== null) { processedValue = objectToArray(value); } else { processedValue = value; } result.push({ key, value: processedValue }); } return result; }
内容的提问来源于stack exchange,提问作者Jasper Erkel
相关产品推荐
相关产品推荐

