使用.Where子句和条件来过滤数组

时间:2018-05-03 16:50:53

标签: c# filter where

我有2个IEnumerable个列表,其中有一个名为GetId()的方法,它返回integer

IEnumerable oldBoats
IEnumerable updatedBoats

我想比较两个列表。如果updatedBoats.getId()返回与oldBoats相比的唯一ID,我想将其添加到列表中。

所以我这样做了:

IEnumerable<Boat> newBoats = updatedBoats
    .Where(c => oldBoats
    .Any(d => d.GetId() != c.GetId())
    .ToList()

oldBoatsnewBoats的当前ID为[1, 2, 3, 4, 5]。我想测试基本情况,但这并没有通过。当newBoats返回none时,c始终返回所有ID的列表。我对d<dependentAssembly> <assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" /> </dependentAssembly> 的排序错了吗?

2 个答案:

答案 0 :(得分:6)

这个怎么样?

public class SwingClass implements ActionListener{

    private JButton b;
    private JFrame f;

    public SwingClass(){
        f = new JFrame();
        f.setVisible(true);
        f.setSize(500, 500);
        b = new JButton("click");
        b.addActionListener(this);
        b.setSize(50, 50);
        f.add(b);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source.equals(b)) {
            jButton2ActionPerformed();
        }
    }

    private void jButton2ActionPerformed() {
        JFileChooser chooser = new JFileChooser();
        chooser.showOpenDialog(null);
        File f = chooser.getSelectedFile();
        String fileName = f.getAbsolutePath();
        try {
            Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + fileName);
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Error");
        }
    }
}

答案 1 :(得分:4)

此代码的作用

IEnumerable<Boat> newBoats = updatedBoats.Where(c=> oldBoats.Any(d =>d.GetId() != c.GetId()).ToList()

粗略地翻译为:&#34;给我所有更新的船只,其ID与至少一个旧船ID不匹配&#34;。那不是你想要的。你想要的逻辑是#34;给我所有更新后的船只,其ID与任何旧船ID都不匹配,并由@zeroef正确指定:

var newBoats = updatedBoats.Where(u => !oldBoats.Any(o => o.GetId() == u.GetId()));  
// This is O(o * n) for # of old boats * # of updates that are new boats, and something like O((o/2)*n) for # of old boats * number of updated old boats

那说,请注意我的评论。使用HashSet<T>

可以更有效地实现这一点
// This is O(n) for # of updated boats
var newBoatIds = new HashSet<Int32>(updatedBoats.Select(b => b.GetId())); 
// This is O(n) for # of old boats
newBoatIds.ExceptWith(oldBoats.Select(b => b.GetId()));

这大大减少了嵌套迭代次数,如果你有很多船只,你会发现差异(特别是如果你的更新中有很多新船)。

HashSet方法适用于ID,但如果您使用ID进行比较,则在Boat类上实现Equals()和GetHashcode(),也可以使其适用于实体本身。