嵌套LINQ for Dictionary

时间:2015-08-11 18:42:39

标签: c# linq

使用C#,我有以下Dictionary

Dictionary<MyClass, List<MyOtherClass>> myDictionary;

我正在尝试编写一个LINQ查询,该查询将在MyOtherClass的每个键值中选择Dictionary的每个实例。到目前为止,我有以下内容:

var whatImLookingFor = myDictionary.SelectMany(x => x.Value).Select(y => y.myProperty == someCompareValue);

这会编译并运行,但whatImLookingFor似乎无法转换为MyOtherClass个对象的集合。如果我尝试说它我想尝试从bool转换为MyOtherClass

在处理LINQ时,是否有一种处理嵌套Dictionaries查询的特殊方式?

3 个答案:

答案 0 :(得分:2)

您实际上是从每个条目中选择一个bool表达式。我认为你的意思是import java.util.ArrayList; import java.util.List; import java.util.Random; public class NeuronNetwork { public static void main(String[] args) { new NeuronNetwork(); } final Integer layers = 2; final Integer hiddenNeuronPerLayer = 10; List<InputNeuron> inputNeurons = new ArrayList<InputNeuron>(); List<OutputNeuron> outputNeurons = new ArrayList<OutputNeuron>(); List<List<Neuron>> hiddenLayers = new ArrayList<List<Neuron>>(); Random r = new Random(System.currentTimeMillis()); public void train(int count) { for (int i = 0; i < count; i++) { fillTraining(); updateOutput(); learn(); } } public int test(int count) { int correct = 0; Double error = 0d; for (int i = 0; i < count; i++) { fillTraining(); updateOutput(); Double calcTotalError = calcTotalError(); error += Math.abs(calcTotalError); if (Math.abs(outputNeurons.get(0).desiredOutput - outputNeurons.get(0).output) < 0.1d) { correct++; } } System.out.println((error / (double) count) + " " + correct + " / " + count); return correct; } public NeuronNetwork() { System.out.println("staret"); // add input neurons for (int i = 0; i < 1; i++) { inputNeurons.add(new InputNeuron(1d)); } // add output neurons for (int i = 0; i < 1; i++) { outputNeurons.add(new OutputNeuron()); } for (Integer layerIndex = 0; layerIndex < layers; layerIndex++) { ArrayList<Neuron> currentHiddenlayer = new ArrayList<Neuron>(); // add input connections for (Integer hiddenNeuronInLayerIndex = 0; hiddenNeuronInLayerIndex < hiddenNeuronPerLayer; hiddenNeuronInLayerIndex++) { Neuron hiddenNeuron = new Neuron(); // add first layer if (layerIndex == 0) { for (Neuron input : inputNeurons) { hiddenNeuron.addInput(input); } } // add inner layers else { for (Neuron input : hiddenLayers.get(layerIndex - 1)) { hiddenNeuron.addInput(input); } } currentHiddenlayer.add(hiddenNeuron); } hiddenLayers.add(currentHiddenlayer); } // add all neurons of last hidden layer to each input neuron for (Neuron out : outputNeurons) { for (Neuron hidden : hiddenLayers.get(hiddenLayers.size() - 1)) { out.addInput(hidden); } } for (int i = 0; i < 10000; i++) { train(100000); if (test(1000) == 1000) { test(10000); break; } } inputNeurons.get(0).output = 0.0d; updateOutput(); System.out.println("OUTPUT " + outputNeurons.get(0).output); } public void fillTraining() { for (InputNeuron input : inputNeurons) { input.output = r.nextDouble(); } if (inputNeurons.get(0).output > 0.7d) { outputNeurons.get(0).desiredOutput = 1d; } else { outputNeurons.get(0).desiredOutput = 0d; } } public Double calcTotalError() { Double error = 0d; for (OutputNeuron out : outputNeurons) { error += Math.pow(out.desiredOutput - out.output, 2); } error *= 0.5d; return error; } public void updateOutput() { for (List<Neuron> layer : hiddenLayers) { for (Neuron n : layer) { n.updateOutput(); } } for (OutputNeuron n : outputNeurons) { n.updateOutput(); } } public void learn() { for (List<Neuron> layer : hiddenLayers) { for (Neuron n : layer) { n.calcNewW(); } } for (OutputNeuron n : outputNeurons) { n.calcNewW(); } for (List<Neuron> layer : hiddenLayers) { for (Neuron n : layer) { n.applyNewW(); } } for (OutputNeuron n : outputNeurons) { n.applyNewW(); } } } import java.util.HashMap; import java.util.HashSet; import java.util.Map.Entry; import java.util.Random; public class Neuron { public static Double rate = 1d; public HashSet<Neuron> inputs = new HashSet<Neuron>(); public HashSet<Neuron> outputs = new HashSet<Neuron>(); public HashMap<Neuron, Double> weights = new HashMap<Neuron, Double>(); public HashMap<Neuron, Double> newWeights = new HashMap<Neuron, Double>(); public Double bias = 0d; public Double output = 0d; static Random r = new Random(System.currentTimeMillis()); /** * add input with default weight of 0.5 * * @param i */ public void addInput(Neuron i) { addInput(i, r.nextDouble() * 0.1d); } public void addInput(Neuron i, Double weight) { inputs.add(i); weights.put(i, weight); i.outputs.add(this); } public void updateOutput() { Double sum = bias; for (Neuron input : inputs) { sum += input.output * weights.get(input); } output = logistic(sum); } public static Double logistic(Double sum) { return 1d / (1d + Math.exp(-sum)); } protected void calcNewW() { // wie wirkt sich der gesamtinput der neurone auf den output der neurone aus? // => output der neurone * (1-output der neurone) Double wert2 = wieWirktSichDerInputAufDenOutputAus(); // wie wirkt sich der output der neurone auf den total error aus? Double wert3 = wieWirktSichDerOutputAufDenTotalErrorAus(); for (Entry<Neuron, Double> connection : weights.entrySet()) { Neuron input = connection.getKey(); Double weight = connection.getValue(); // wie wirkt sich das w auf den input der neurone aus? // => output der quellneurone Double wert1 = input.output; Double result = wert1 * wert2 * wert3; newWeights.put(input, weight - rate * result); } bias -= wert3 * rate; } protected Double wieWirktSichDerOutputAufDenTotalErrorAus() { // => ist zunächst die summe für alle zielneuronen => wie wirkt dich der output auf den fehler der zielneurone aus Double wert3 = 0d; for (Neuron out : outputs) { // ==> wie wirkt sich der netzinput der nächsten neurone auf den fehlerwert der nächsten neurone aus // 1. wie wirkt sich der input auf den output aus => output der neurone * (1-output der neurone) Double wert3_a_a = out.wieWirktSichDerInputAufDenOutputAus(); // 2. wie wirkt sich der output auf den fehler aus Double wert3_a_b = out.wieWirktSichDerOutputAufDenTotalErrorAus(); // => rekursoin bis zur out neurone, und dort // -(EXPECTED-OUTPUT) // ==mal // ==> wie wirkt sich der output der neurone auf dern input der nächsten neurone aus => das aktuelle w Double wert3_b = out.weights.get(this); wert3 += wert3_a_a * wert3_a_b * wert3_b; } return wert3; } private double wieWirktSichDerInputAufDenOutputAus() { return output * (1d - output); } public void applyNewW() { weights = newWeights; } } public class InputNeuron extends Neuron { public InputNeuron(Double output) { this.output = output; } } public class OutputNeuron extends Neuron { public Double desiredOutput = 1d; protected Double wieWirktSichDerOutputAufDenTotalErrorAus() { return -(desiredOutput - output); } } 代替Where这样:

Select

答案 1 :(得分:2)

正如其他人所提到的那样,你通过这样做来选择一个bool列表;您可以按照字典枚举键值对的顺序,有效地选择对someCompareValue测试列表中每个值的结果。

您可以使用代替第二个选择的位置。它有点冗长,但是当查询变得更复杂时,我倾向于发现这种形式的linq更易于维护:

    var whatImLookingFor = from kvp in myDictionary
                           from v in kvp.Value
                           where v.myProperty == someCompareValue
                           select v;

答案 2 :(得分:0)

您希望使用Where而不是Select,甚至不需要SelectMany - 您可以将其写为:

var whatImLookingFor = myDictionary.Values.Where(y => y.myProperty == someCompareValue);

希望有所帮助!