Let's say I have the following data (in pseudo-code for readability):
var myVariations = [
{ Name = "Color", Values = ["Red", "Yellow", "Green" /*, etc. */] },
{ Name = "Size", Values = ["S", "M", "L" /*, etc. */] },
{ Name = "Length", Values = ["34", "35", "36" /*, etc. */] },
/* and so on...(up to 5 total) */
];
And I can get that data with LINQ like so:
var myVariations = myProduct.Variations.ToList();
How can I go about mapping those variations into a structure like this (for the eBay Trading API):
var ebayVariations = [
{
Name = "Red-S-34",
Value = [
// yes, these are arrays with only one item
{ Name = "Color", Valu开发者_Python百科es = [{Value = "Red"}] },
{ Name = "Size", Values = [{Value = "S"}] },
{ Name = "Length", Values = [{Value = "34" }] }
]
},
/* etc for all possible combinations */
];
Obviously the fact that the Values
array holds only one value is a bit strange; but with eBay's Trading API if I list multiple values in a single Variation (which is easy to do compared to this recursive stuff) it complains. So alternatively, if you are familiar with the eBay Trading API, how can I get this to work in an "optimal" fashion, in-line with the way eBay intended Variations to be listed (called via AddFixedPricedItem, if you care).
I don't know anything about the eBay Trading API, but here's an article on computing a Cartesian Product with LINQ (the very last step drops the recursion in favor of aggregation).
I've changed terminology insignificantly, but wrote clarifying comments.
public IEnumerable<Combination> GetCombinations(Variation[] variations, int variationIndex, IEnumerable<VariationPosition> aggregatedPositions)
{
// We should choose one position from every variation,
// so we couldn't produce combination till we reach end of array.
if (variationIndex < variations.Length)
{
// Pick current variation.
var currentVariation = variations[variationIndex];
// Every variation has list of possible positions (Color could be Green, Redm, Blue, etc.).
// So we should walk through all the positions
foreach (var val in currentVariation.Positions)
{
// Current position. Variation's name will be used during creating result Combination.
var position = new VariationPosition()
{
Name = currentVariation.Name,
Value = val
};
// Add position to already aggregated on upper levels of recursion positions.
var newPositions = aggregatedPositions.Concat(Enumerable.Repeat(position, 1));
// So we picked some variation position
// Let's go deeper.
var combinations = this.GetCombinations(variations, variationIndex + 1, newPositions );
// This piece of code allows us return combinations in iterator fashion.
foreach (var combination in combinations)
{
yield return combination;
}
}
}
else
{
// We reached end of variations array
// I mean we have one position of every variation.
// We concatenate name of positions in order to create string like "Red-S-34"
var name = aggregatedPositions.Aggregate("", (res, v) => res += v.Name);
// This code is a little bit naive, I'm too lazy to create proper infrastructure,
// But its mission is to create content for property Value of your ebayVariations item.
var value = aggregatedPositions
.Select(v => new { Name = v.Name, Values = new[] { new { Value = v.Value } } })
.ToArray();
// And we return completed combination.
yield return new Combination()
{
Name = name,
Value = value,
};
}
}
And usage:
var allCombinations = this.GetCombinations(inputVariations, 0, new VariationPosition[0]).ToArray();
精彩评论