2016-11-20 35 views
3

如何渲染此映射 - 減少javascript函數爲等效的c#LINQ Select-Aggregate語法?如何渲染此映射 - 將JavaScript代碼還原爲等效的LINQ Select-Aggregate?

/** 
* Multiply transforms into one. 
* 
* @param {Array} input transforms array 
* @return {Array} output matrix array 
*/ 
exports.transformsMultiply = function(transforms) { 

    // convert transforms objects to the matrices 
    transforms = transforms.map(function(transform) { 
     if (transform.name === 'matrix') { 
      return transform.data; 
     } 
     return transformToMatrix(transform); 
    }); 

    // multiply all matrices into one 
    transforms = { 
     name: 'matrix', 
     data: transforms.reduce(function(a, b) { 
      return multiplyTransformMatrices(a, b); 
     }) 
    }; 

    return transforms; 

}; 
+0

您有一本字典作爲本貼子的標籤。所以字典看起來像這樣:var matrices = transforms.GroupBy(x => x.a,y => y.b) .ToDictionary(x => x.Key,y => y.ToList()); – jdweng

+0

@jdweng謝謝。但是如果我還有一個字典作爲輸入參數「變換」呢?例如:Dictionary ,其中decimal []是矩陣係數的數組? –

+0

單個數組如何映射到(a,b)? – jdweng

回答

2

直接等同會是這個樣子:

public Transform TransformsMultiply(IEnumerable<Transform> transforms) 
{ 
    var matrices = transforms.Select(transform => 
     transform.Name == "matrix" 
      ? transform.Data 
      : transformToMatrix(transform)); 

    return new Transform 
    { 
     Name = "matrix", 
     Data = matrices.Aggregate((a, b) => 
      multiplyTransformMatrices(a, b)); 
    }; 
} 

你當然需要定義Transform類和transformToMatrixmultiplyTransformMatrices方法;

儘管區分Name屬性的轉換類型不是慣用的C#。這將是好得多,如果你創建了每種類型的抽象基Transform類型和子類變換:

public abstract class Transform { /* ... */ } 

public class Matrix : Transform 
{ 
    public int[,] Data { get; set; } 
} 

public class OtherTypeOfTransform : Transform 
{ 
    /* ... */ 
} 

方法的第一部分將隨後樣子:

var matrices = transforms.Select(transform => 
    transform is Matrix 
     ? transform.Data 
     : transformToMatrix(transform)); 

但是,這並不是非常面向對象,因爲transformToMatrix需要知道如何將每種類型的轉換轉換爲矩陣。您應該考慮在基類中添加抽象方法ToMatrix並在子類中實現它,從而將自身轉換爲矩陣到每個子類的責任。

public abstract class Transform 
{ 
    public abstract Matrix ToMatrix(); 
} 

public class Matrix : Transform 
{ 
    public int[,] Data { get; set; } 

    public Matrix ToMatrix() { return this; } 
} 

public class OtherTypeOfTransform : Transform 
{ 
    public Matrix ToMatrix() 
    { 
     // Type-specific implementation 
    } 
} 

在此之後,執行應該是這樣的:

public Matrix TransformsMultiply(IEnumerable<Transform> transforms) 
{ 
    return new Matrix 
    { 
     Data = transforms 
      .Select(transform => transform.ToMatrix()) 
      .Aggregate((a, b) => multiplyTransformMatrices(a, b)); 
    }; 
} 

移動倍增到Matrix可以使這個更漂亮:

public Matrix TransformsMultiply(IEnumerable<Transform> transforms) 
{ 
    return new Matrix 
    { 
     Data = transforms 
      .Select(transform => transform.ToMatrix()) 
      .Aggregate((a, b) => a.MultiplyBy(b)); 
    }; 
} 

這就是我將如何轉換這JavaScript轉化爲慣用的面向對象的C#代碼。

編輯

你問我如何使用的Dictionary<string, decimal[]>代替IEnumerable<Transform>實現這一點,所以在這裏它是:

public KeyValuePair<string, decimal[]> TransformsMultiply(
    Dictionary<string, decimal[]> transforms) 
{ 
    var matrices = transforms.Select(kvp => 
     kvp.Key == "matrix" 
      ? kvp.Value 
      : transformToMatrix(kvg.Value)); 

    return new KeyValuePair<string, int>(
     "matrix", 
     matrices.Aggregate((a, b) => multiplyTransformMatrices(a, b)); 
} 

一個Dictionary<TKey, TValue>IEnumerable<KeyValuePair<TKey, TValue>>,所以在這種解決方案中,變換由KeyValuePair<string, decimal[]>表示。

請注意,字典密鑰是唯一的,所以您只能使用密鑰"matrix"進行一次轉換。我不確定這是你想要的。

這種解決方案的缺點是:

  • 你只能擁有各類型,因爲變換的一個實例字典鍵唯一
  • 它掩蓋了代碼的意圖,並使其更難閱讀(在我看來,
  • 邏輯上屬於轉換本身的行爲(如何將其轉換爲矩陣以及如何將矩陣乘以另一個矩陣)現在未被封裝,並且它位於transformToMatrixmultiplyTransformMatrices方法中。

如果你真的想要的變換,而不是一個名爲類的通用集裝箱,可以使用Tuple<T, U>

public Tuple<string, decimal[]> TransformsMultiply(
    IEnumerable<Tuple<string, decimal[]>> transforms) 
{ 
    var matrices = transforms.Select(t => 
     t.Item1 == "matrix" ? t.Item2 : transformToMatrix(t.Item2)); 

    return new Tuple<string, decimal[]>(
     "matrix", 
     matrices.Aggregate((a, b) => multiplyTransformMatrices(a, b))); 
} 

在這裏,你可以有多種變換名稱相同,但第二個和第三個缺點上面提到的仍然適用。

+1

謝謝,這非常有幫助! –

+0

如果我有一本字典作爲'變換'呢?例如:Dictionary ,其中decimal []是矩陣係數的數組?名稱和數據是字典條目的鍵和值屬性? –

+0

這也可以,但只有一個字典項目可以有關鍵矩陣。我不確定這是你想要的。我會用字典添加一個答案。但我不會推薦這樣做。 –