从数组中删除未定义的元素

3

我有一个表格,从中提取数据并添加到一个数组的子数组中。问题是,如果其中一个单元格为空,它会以“未定义”的形式出现在数组中。我尝试使用if语句判断最后一个元素是否为undefined,如果是的话就使用.pop()方法将该元素删除。但我仍然会得到undefined的元素。以下是我的代码和实时 演示

HTML代码:

<table id="contactlisttable">
    <tr>
        <th>Name</th>
        <th>Title</th>
        <th>Phone</th>
    </tr>
    <tr>
        <td class="contactlist contactlistlastfirst">Joey</td>
        <td class="contactlist contactlisttitle">webdesigner</td>
        <td class="contactlist contactlistphone"></td>
    </tr>
    <tr>
        <td class="contactlist contactlistlastfirst">Anthony</td>
        <td class="contactlist contactlisttitle">webdesigner</td>
        <td class="contactlist contactlistphone">5555555</td>
    </tr>
</table> 


JavaScript :

//IE9+ compatable solution
$(function(){
    var results = [], row; 
    $('#contactlisttable').find('th, td').each(function(){
        if(!this.previousElementSibling){ //New Row?
            row = []; 
            results.push(row); 
            if($(this) === 'undefined'){//Remove undefined elements
                row.pop();
            }
        }
        row.push(this.textContent || this.innerText); //Add the values (textContent is standard while innerText is not)       
    }); 
    console.log(results); 
}); 


如果该字段未定义,您想在数组中放置什么? - Jivings
这也会消除数组的“稀疏”特性。那么为什么不在那时使用对象呢? - Travis J
5个回答

2

jsFiddle示例

不要使用条件语句,而是利用你的HTML结构。首先按表格行进行选择,然后迭代子tdth元素。你还可以利用jQuery的text方法来代替功能检测,这样更可靠。

var results = [];
$('#contactlisttable tr').each(function(){
 var row = [];
 $(this).find('td,th').each(function(){
     row.push($(this).text());
 });
 results.push(row);
});
console.log(results);

+1 一个内部循环更有意义。虽然你可以使用.map()来创建数组,但你需要解决jQuery自动展开内部.map()的问题。 - cookie monster

1

如果不匹配,不要推入栈中,而是一开始就不要推入。

从您的jsfiddle更新:

//IE9+ compatable solution
$(function(){
    var results = [], row; 
    $('#contactlisttable').find('th, td').each(function(){
        if(!this.previousElementSibling && typeof(this) != 'undefined'){ //New Row?
            row = []; 
            results.push(row); 
        }
        row.push(this.textContent || this.innerText); //Add the values (textContent is standard while innerText is not)       
    }); 
    console.log(results); 
}); 

1
你也可以通过这种方式避免添加未定义(或实际为空的)元素:
$('#contactlisttable').find('th, td').each(function(){
    if(!this.previousElementSibling){ //New Row?
        row = [];
        results.push(row);
    }
    if(!(this.textContent == '')){
        row.push(this.textContent || this.innerText);            
    }
}); 

Travis J的答案对于这种情况更加合适。 - Julio

0
你可以添加一个像 underscore 和 lodash 中那样的紧凑方法...
Array.prototype.compact = function() {
    return this.filter(function(x){
        return x !== undefined;
    });
}

console.log([1,2, '', undefined, 'e', undefined].compact()); // [ 1, 2, '', 'e' ]

由于您正在覆盖一个原生的原型,所以最好添加一个对compact本地实现的检查。

或者,只需


如果compact()只适用于数组,为什么要将其放在Function.prototype上? - cookie monster
抱歉,早上太困了 :P... 已更新。 - brbcoding

0

如果想要知道某个东西是否未定义,不要仅仅与"undefined"进行比较,使用typeof()。

所以你想要做的是:

if (typeof(this) === "undefined")

2
这永远不可能成立,因为你正在构造一个jQuery对象。该对象的类型永远不会返回undefined。虽然我没有投反对票,但只是指出这一点。 - Travis J
确实,只是太快了。已经纠正。 - Yabada
typeof不是一个函数。你不需要括号。 - canon
1
它可以避免眼睛流血。 - Yabada
@EoiFirst,你对return也这样做吗,例如:return(true)?让非函数关键字看起来像函数调用会让我眼花缭乱的。 ;) - canon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接