Smart way to concat two Sets - c#-4.0

Say I have two sets
var Set1 = new[] { "A", "B", "C" };
var Set2 = new[] { "1", "2", "3" };
To concat these two sets usually i do
foreach (string itm1 in Set1 )
{
foreach (string itm2 in Set2)
{
Console.WriteLine(itm1 + itm2);
}
}
Is there any LINQ style of getting the same result?

var strs = Set1.SelectMany(s1 => Set2.Select(s2 => s1 + s2))
foreach(string s in strs)
{
Console.WriteLine(s);
}
alternatively using the query syntax:
var strs = from s1 in Set1
from s2 in Set2
select s1 + s2;

Try
var concatSet =Set1
.SelectMany(
item => Set2,
(i1, i2) => (i1 + i2)
);

Related

How do I get the result of 3 random numbers using random operator?

I have trying to get the result of the 3 random number using random operators. This is what have done so far. Could anyone explain or show how i can do this
fun rightEquation(){
var num5 = 1 + generator.nextInt(20)
var num6 = 1 + generator.nextInt(20)
var num7 = 1 + generator.nextInt(20)
var num8 = 1 + generator.nextInt(20)
var total = mutableListOf<String>()
eq5 = "(" + num5 + "" + operation() + "" + num6 + ")" + operation() + "" + num7
}
fun operation(): String {
return when (generator.nextInt(4)){
0 -> "-"
1 -> "+"
2 -> "/"
3 -> "*"
else ->""
}
Since Kotlin 1.3, there’s a built-in method to fetch a random item from a list: random()
fun rightEquation(): String {
return "(${randomNumber()}${randomOperator()}${randomNumber()})${randomOperator()}${randomNumber()}"
}
fun randomOperator(): String {
val operators = listOf("-", "+", "/", "*")
return operators.random()
}
fun randomNumber(): String {
val number = 1 + generator.nextInt(20)
return number.toString()
}
This will generate an equation and calculate the result of it:
fun evaluate(str: String): Double {
data class Data(val rest: List<Char>, val value: Double)
return object : Any() {
fun parse(chars: List<Char>): Double {
return getExpression(chars.filter { it != ' ' })
.also { if (it.rest.isNotEmpty()) throw RuntimeException("Unexpected character: ${it.rest.first()}") }
.value
}
private fun getExpression(chars: List<Char>): Data {
var (rest, carry) = getTerm(chars)
while (true) {
when {
rest.firstOrNull() == '+' -> rest = getTerm(rest.drop(1)).also { carry += it.value }.rest
rest.firstOrNull() == '-' -> rest = getTerm(rest.drop(1)).also { carry -= it.value }.rest
else -> return Data(rest, carry)
}
}
}
fun getTerm(chars: List<Char>): Data {
var (rest, carry) = getFactor(chars)
while (true) {
when {
rest.firstOrNull() == '*' -> rest = getTerm(rest.drop(1)).also { carry *= it.value }.rest
rest.firstOrNull() == '/' -> rest = getTerm(rest.drop(1)).also { carry /= it.value }.rest
else -> return Data(rest, carry)
}
}
}
fun getFactor(chars: List<Char>): Data {
return when (val char = chars.firstOrNull()) {
'+' -> getFactor(chars.drop(1)).let { Data(it.rest, +it.value) }
'-' -> getFactor(chars.drop(1)).let { Data(it.rest, -it.value) }
'(' -> getParenthesizedExpression(chars.drop(1))
in '0'..'9', ',' -> getNumber(chars)
else -> throw RuntimeException("Unexpected character: $char")
}
}
fun getParenthesizedExpression(chars: List<Char>): Data {
return getExpression(chars)
.also { if (it.rest.firstOrNull() != ')') throw RuntimeException("Missing closing parenthesis") }
.let { Data(it.rest.drop(1), it.value) }
}
fun getNumber(chars: List<Char>): Data {
val s = chars.takeWhile { it.isDigit() || it == '.' }.joinToString("")
return Data(chars.drop(s.length), s.toDouble())
}
}.parse(str.toList())
}
val num1 = (1..20).random()
val num2 = (1..20).random()
val num3 = (1..20).random()
val op1 = listOf('+', '-', '*', '/').random()
val op2 = listOf('+', '-', '*', '/').random()
val equation = "( $num1 $op1 $num2 ) $op2 $num3"
println("$equation = ${evaluate(equation)}")

Add slash to string every n characters [duplicate]

I have a string which contains binary digits. How to separate it in to pairs of digits?
Suppose the string is:
let x = "11231245"
I want to add a separator such as ":" (i.e., a colon) after each 2 characters.
I would like the output to be:
"11:23:12:45"
How could I do this in Swift ?
Swift 5.2 • Xcode 11.4 or later
extension Collection {
func unfoldSubSequences(limitedTo maxLength: Int) -> UnfoldSequence<SubSequence,Index> {
sequence(state: startIndex) { start in
guard start < endIndex else { return nil }
let end = index(start, offsetBy: maxLength, limitedBy: endIndex) ?? endIndex
defer { start = end }
return self[start..<end]
}
}
func every(n: Int) -> UnfoldSequence<Element,Index> {
sequence(state: startIndex) { index in
guard index < endIndex else { return nil }
defer { let _ = formIndex(&index, offsetBy: n, limitedBy: endIndex) }
return self[index]
}
}
var pairs: [SubSequence] { .init(unfoldSubSequences(limitedTo: 2)) }
}
extension StringProtocol where Self: RangeReplaceableCollection {
mutating func insert<S: StringProtocol>(separator: S, every n: Int) {
for index in indices.every(n: n).dropFirst().reversed() {
insert(contentsOf: separator, at: index)
}
}
func inserting<S: StringProtocol>(separator: S, every n: Int) -> Self {
.init(unfoldSubSequences(limitedTo: n).joined(separator: separator))
}
}
Testing
let str = "112312451"
let final0 = str.unfoldSubSequences(limitedTo: 2).joined(separator: ":")
print(final0) // "11:23:12:45:1"
let final1 = str.pairs.joined(separator: ":")
print(final1) // "11:23:12:45:1"
let final2 = str.inserting(separator: ":", every: 2)
print(final2) // "11:23:12:45:1\n"
var str2 = "112312451"
str2.insert(separator: ":", every: 2)
print(str2) // "11:23:12:45:1\n"
var str3 = "112312451"
str3.insert(separator: ":", every: 3)
print(str3) // "112:312:451\n"
var str4 = "112312451"
str4.insert(separator: ":", every: 4)
print(str4) // "1123:1245:1\n"
I'll go for this compact solution (in Swift 4) :
let s = "11231245"
let r = String(s.enumerated().map { $0 > 0 && $0 % 2 == 0 ? [":", $1] : [$1]}.joined())
You can make an extension and parameterize the stride and the separator so that you can use it for every value you want (In my case, I use it to dump 32-bit space-operated hexadecimal data):
extension String {
func separate(every stride: Int = 4, with separator: Character = " ") -> String {
return String(enumerated().map { $0 > 0 && $0 % stride == 0 ? [separator, $1] : [$1]}.joined())
}
}
In your case this gives the following results:
let x = "11231245"
print (x.separate(every:2, with: ":")
$ 11:23:12:45
Swift 5.3
/// Adds a separator at every N characters
/// - Parameters:
/// - separator: the String value to be inserted, to separate the groups. Default is " " - one space.
/// - stride: the number of characters in the group, before a separator is inserted. Default is 4.
/// - Returns: Returns a String which includes a `separator` String at every `stride` number of characters.
func separated(by separator: String = " ", stride: Int = 4) -> String {
return enumerated().map { $0.isMultiple(of: stride) && ($0 != 0) ? "\(separator)\($1)" : String($1) }.joined()
}
Short and simple, add a let or two if you want
extension String {
func separate(every: Int, with separator: String) -> String {
return String(stride(from: 0, to: Array(self).count, by: every).map {
Array(Array(self)[$0..<min($0 + every, Array(self).count)])
}.joined(separator: separator))
}
}
let a = "separatemepleaseandthankyou".separate(every: 4, with: " ")
a is
sepa rate mepl ease andt hank you
Its my code in swift 4
let x = "11231245"
var newText = String()
for (index, character) in x.enumerated() {
if index != 0 && index % 2 == 0 {
newText.append(":")
}
newText.append(String(character))
}
print(newText)
Outputs 11:23:12:45
My attempt at that code would be:
func insert(seperator: String, afterEveryXChars: Int, intoString: String) -> String {
var output = ""
intoString.characters.enumerate().forEach { index, c in
if index % afterEveryXChars == 0 && index > 0 {
output += seperator
}
output.append(c)
}
return output
}
insert(":", afterEveryXChars: 2, intoString: "11231245")
Which outputs
11:23:12:45
let y = String(
x.characters.enumerate().map() {
$0.index % 2 == 0 ? [$0.element] : [$0.element, ":"]
}.flatten()
)
A simple One line of code for inserting separater ( Swift 4.2 ):-
let testString = "123456789"
let ansTest = testString.enumerated().compactMap({ ($0 > 0) && ($0 % 2 == 0) ? ":\($1)" : "\($1)" }).joined() ?? ""
print(ansTest) // 12:34:56:78:9
Swift 4.2.1 - Xcode 10.1
extension String {
func insertSeparator(_ separatorString: String, atEvery n: Int) -> String {
guard 0 < n else { return self }
return self.enumerated().map({String($0.element) + (($0.offset != self.count - 1 && $0.offset % n == n - 1) ? "\(separatorString)" : "")}).joined()
}
mutating func insertedSeparator(_ separatorString: String, atEvery n: Int) {
self = insertSeparator(separatorString, atEvery: n)
}
}
Usage
let testString = "11231245"
let test1 = testString.insertSeparator(":", atEvery: 2)
print(test1) // 11:23:12:45
var test2 = testString
test2.insertedSeparator(",", atEvery: 3)
print(test2) // 112,312,45
I'm little late here, but i like to use regex like in this:
extension String {
func separating(every: Int, separator: String) -> String {
let regex = #"(.{\#(every)})(?=.)"#
return self.replacingOccurrences(of: regex, with: "$1\(separator)", options: [.regularExpression])
}
}
"111222333".separating(every: 3, separator: " ")
the output:
"111 222 333"
extension String{
func separate(every: Int) -> [String] {
return stride(from: 0, to: count, by: every).map {
let ix0 = index(startIndex, offsetBy: $0);
let ix1 = index(after:ix0);
if ix1 < endIndex {
return String(self[ix0...ix1]);
}else{
return String(self[ix0..<endIndex]);
}
}
}
/// or O(1) implementation (without count)
func separate(every: Int) -> [String] {
var parts:[String] = [];
var ix1 = startIndex;
while ix1 < endIndex {
let ix0 = ix1;
var n = 0;
while ix1 < endIndex && n < every {
ix1 = index(after: ix1);
n += 1;
}
parts.append(String(self[ix0..<ix1]));
}
return parts;
}
"asdf234sdf".separate(every: 2).joined(separator: ":");
A simple String extension that doesn't require the original string to be a multiple of the step size (increment):
extension String {
func inserted(_ newElement: Character,atEach increment:Int)->String {
var newStr = self
for indx in stride(from: increment, to: newStr.count, by: increment).reversed() {
let index = String.Index(encodedOffset: indx)
newStr.insert(newElement, at: index)
}
return newStr
}
}

Counting different Characters in Swift

I am new to swift and I am trying to count the different characters in a string but my code returns the value for the whole String
for example:
var string aString = "aabb"
aString.characters.count() //returns 5
counter = 0
let a = "a"
for a in aString.characters {
counter++
} //equally returns 5
Can somebody explain why this is happening and how I could count the different chars?
It looks there is some confusion about what you really need.
I tried to answer to the 5 most likely interpretations.
var word = "aabb"
let numberOfChars = word.characters.count // 4
let numberOfDistinctChars = Set(word.characters).count // 2
let occurrenciesOfA = word.characters.filter { $0 == "A" }.count // 0
let occurrenciesOfa = word.characters.filter { $0 == "a" }.count // 2
let occurrenciesOfACaseInsensitive = word.characters.filter { $0 == "A" || $0 == "a" }.count // 2
print(occurrenciesOfA)
print(occurrenciesOfa)
print(occurrenciesOfACaseInsensitive)
check this
var aString = "aabb"
aString.characters.count // 4
var counter = 0
let a = "a" // you newer use this in your code
for thisIsSingleCharacterInStringCharactersView in aString.characters {
counter++
}
print(counter) // 4
it simply increase your counter for each character
to calculate number of different characters in you string, you probably can use something 'more advanced', like in next example
let str = "aabbcsdfaewdsrsfdeewraewd"
let dict = str.characters.reduce([:]) { (d, c) -> Dictionary<Character,Int> in
var d = d
let i = d[c] ?? 0
d[c] = i+1
return d
}
print(dict) // ["b": 2, "a": 4, "w": 3, "r": 2, "c": 1, "s": 3, "f": 2, "e": 4, "d": 4]
You code is quite faulty: it should probably start with
let aString = "aabb"
The solutions is to get the characters, put them into a set (unique) and then counting the members of the set:
let differentChars = Set(aString.characters).count
Correctly returns
2
The characters property is deprecated, you can use components(separatedBy:) to find how many characters in a String. eg,
extension String {
public func numberOfOccurrences(_ string: String) -> Int {
return components(separatedBy: string).count - 1
}
}
let aString = "aabbaa"
let aCount = aString.numberOfOccurrences("a") // aCount = 4
Updated #Luca Angeletti's answer for Swift5.3 because characters property is unavailable in newer swift version.
var word = "aabb"
let numberOfChars = word.count // 4
let numberOfDistinctChars = Set(word).count // 2
let occurrenciesOfA = word.filter { $0 == "A" }.count // 0
let occurrenciesOfa = word.filter { $0 == "a" }.count // 2
let occurrenciesOfACaseInsensitive = word.filter { $0 == "A" || $0 == "a" }.count // 2
print(numberOfChars)
print(numberOfDistinctChars)
print(occurrenciesOfA)
print(occurrenciesOfa)
print(occurrenciesOfACaseInsensitive)
Construct a dictionary out of a sequence of (key, value) pairs. If we can guarantee that the keys are unique, we can use Dictionary(uniqueKeysWithValues:).
func characterFrequencies(of string: String) -> Dictionary<String.Element, Int> {
let frequencyPair = string.map { ($0, 1) }
return Dictionary(frequencyPair, uniquingKeysWith: +)
}
Usage : print(characterFrequencies(of: "Happy"))
Result : ["a": 1, "H": 1, "y": 1, "p": 2]
func repeatedCharaterPrint(inputArray: [String]) -> [String:Int] {
var dict = [String:Int]()
if inputArray.count > 0 {
for char in inputArray {
if let keyExists = dict[char], keyExists != nil {
dict[char] = Int(dict[char] ?? 0) + 1
}else {
dict[char] = 1
}
}
}
return dict
}
let aa = ["a","s","f","s","l","s"]
print(repeatedCharaterPrint(inputArray: aa))
//Answer : "["s": 3, "l": 1, "a": 1, "f": 1]"
This solution is written using hash function , so computation time would be O(1). good for long strings.
//Extension On String and Characters to get Ascii values and Char from Ascii
extension Character {
//Get Ascii Value of Char
var asciiValue:UInt32? {
return String(self).unicodeScalars.filter{$0.isASCII}.first?.value
}
}
extension String {
//Char Char from Ascii Value
init(unicodeScalar: UnicodeScalar) {
self.init(Character(unicodeScalar))
}
init?(unicodeCodepoint: Int) {
if let unicodeScalar = UnicodeScalar(unicodeCodepoint) {
self.init(unicodeScalar: unicodeScalar)
} else {
return nil
}
}
static func +(lhs: String, rhs: Int) -> String {
return lhs + String(unicodeCodepoint: rhs)!
}
static func +=(lhs: inout String, rhs: Int) {
lhs = lhs + rhs
}
}
extension String {
///Get Char at Index from String
var length: Int {
return self.characters.count
}
subscript (i: Int) -> String {
return self[Range(i ..< i + 1)]
}
func substring(from: Int) -> String {
return self[Range(min(from, length) ..< length)]
}
func substring(to: Int) -> String {
return self[Range(0 ..< max(0, to))]
}
subscript (r: Range<Int>) -> String {
let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
upper: min(length, max(0, r.upperBound))))
let start = index(startIndex, offsetBy: range.lowerBound)
let end = index(start, offsetBy: range.upperBound - range.lowerBound)
return self[Range(start ..< end)]
}
}
//Program :
let strk = "aacncjkvkevkklvkdsjkbvjsdbvjkbsdjkvbjdsbvjkbsvbkjwlnkneilhfleknkeiohlgblehgilkbskdbvjdsbvjkdsbvbbvsbdvjlbsdvjbvjkdbvbsjdbjsbvjbdjbjbjkbjkvbjkbdvjbdjkvbjdbvjdbvjbvjdsbjkvbdsjvbkjsbvadvbjkenevknkenvnekvjksbdjvbjkbjbvbkjvbjdsbvjkbdskjvbdsbvjkdsbkvbsdkjbvkjsbvjsbdjkvbdsbvjkbdsvjbdefghaj"
print(strk)
//Declare array of fixes size 26 (characters) or you can say it as a hash table
var freq = [Int](repeatElement(0, count: 26))
func hashFunc(char : Character) -> UInt32 {
guard let ascii = char.asciiValue else {
return 0
}
return ascii - 97 //97 used for ascii value of a
}
func countFre(string:String) {
for i in 0 ... string.characters.count-1 {
let charAtIndex = string[i].characters.first!
let index = hashFunc(char: charAtIndex)
let currentVal = freq[Int(index)]
freq[Int(index)] = currentVal + 1
//print("CurrentVal of \(charAtIndex) with index \(index) is \(currentVal)")
}
for charIndex in 0 ..< 26 {
print(String(unicodeCodepoint: charIndex+97)!,freq[charIndex])
}
}
countFre(string: strk)

How to move characters to certain points

I have a problem in which I have to SWAP or move characters and integers. Like I have any characters A . now I have some cases, like
NOTE:- Have to use characters A-Z and integers 0-9
A, now I want that when my program run I assign some integer value to this character, If I assign value 3 to this character then A will become D or it just move to 3 places.
Now if I have a character like Y and I add 4 then it will become C means after Z it will again start from character A.
Same condition I have to follow with Integer if i have 9 and we assign 3 to it then it will become 2 because loop start from 0 not from 1. Means we have to use only 0-9 integers.
I know that i am using wrong name to question but i have no idea that what lines i have to use for that kind of question.
Hope you understand my problem.
Thanks in advance.
Try the below extension method, which does the following:
It creates 2 dictionaries in order to speed up the key look up in the alphabet
Will parse the inputString variable, split it in substrings of the length of the moveString variable's length (or the remainder)
On every substring, it will evaluate each character in order to detect if it's a digit
If it's not a digit, it looks up for the value in the swappedAlphabet dictionary, by using the int key
If it's a digit, it applies a modulo operation on the sum of the digit and the corresponding moveint value
It finally aggregates all the characters in the final result string
Here's the code:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
string
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string inputString = "ABC123D", moveString = "12";
var result = inputString.Swap(alphabet, moveString);
Console.WriteLine(result);
}
}
static class ExtensionMethods
{
public static Dictionary<TValue, TKey>
SwapKeysValues<TKey, TValue>(this Dictionary<TKey, TValue> input)
{
var result = new Dictionary<TValue, TKey>();
input.ToList().ForEach((keyValuePair) =>
{
result.Add(keyValuePair.Value, keyValuePair.Key);
});
return result;
}
public static string Swap(
this string input,
string alphabet,
string move)
{
Dictionary<char, int>
alphabetDictionary = new Dictionary<char, int>();
for (int i = 0; i < alphabet.Length; i++)
{
alphabetDictionary.Add(alphabet[i], i);
}
var swapedAlphabet = alphabetDictionary.SwapKeysValues();
return Enumerable
.Range(0, (int)Math.Ceiling(input.Length / (move.Length * 1M)))
.ToList()
.Aggregate<int, string>("", (s, i) =>
{
var l = i * move.Length + move.Length;
var cInput = input.Substring(i * move.Length,
(l > input.Length)
? input.Length - i * move.Length : move.Length);
return s + cInput
.Select((c, index) =>
{
int intCandidate;
if (!Int32.TryParse(c.ToString(), out intCandidate))
{
var length = (alphabetDictionary[c] +
Int32.Parse(move[index].ToString()));
return
swapedAlphabet[(alphabet.Length > length)
? length : length % alphabet.Length];
}
else
{
var moveInt = Int32.Parse(move[index].ToString());
return Char.Parse(((intCandidate + moveInt) % 10)
.ToString());
}
})
.Aggregate<char, string>("", (a, b) => a + b);
});
}
}
Another alternative you have is relying on the in-built character/integer types which follow the order you want; with an additional consideration: if you account for caps, it would deliver caps ("B" after "A" and "b" after "a"). The only thing you need to worry about is making sure that the iterations will be limited to the A-Z/0-9 boundaries. Sample code:
public string moveChar(string inputChar, int noPos)
{
string outChar = checkBoundaries(inputChar, noPos);
if (outChar == "")
{
outChar = basicConversion(inputChar, noPos);
}
return outChar;
}
public string basicConversion(string inputChar, int noPos)
{
return Convert.ToString(Convert.ToChar(Convert.ToInt32(Convert.ToChar(inputChar)) + noPos));
}
public string checkBoundaries(string inputChar, int noPos)
{
string outString = "";
int count1 = 0;
do
{
count1 = count1 + 1;
string curTemp = basicConversion(inputChar, 1);
if (inputChar.ToLower() == "z" || curTemp.ToLower() == "z")
{
if (inputChar.ToLower() != "z")
{
noPos = noPos - count1;
}
inputChar = "a";
outString = "a";
if (inputChar == "Z" || curTemp == "Z")
{
inputChar = "A";
outString = "A";
}
count1 = 1;
}
else if (inputChar == "9" || curTemp == "9")
{
if (inputChar != "9")
{
noPos = noPos - count1;
}
inputChar = "0";
outString = "0";
count1 = 1;
}
else
{
inputChar = curTemp;
outString = inputChar;
}
} while (count1 < noPos);
return outString;
}
It expects strings (just one character (letter or number) per call) and you can call it simply by using: moveChar("current letter or number", no_of_pos_to_move). This version accounts just for "positive"/"forwards" movements but it might easily be edited to account for the inverse situation.
Here's a very simple way to implement a Caesar Cipher with the restrictions you defined.
var shift = 3;
var input = "HELLO WORLD 678";
var classAlphabets = new Dictionary<UnicodeCategory, string>
{
{ UnicodeCategory.SpaceSeparator, " " },
{ UnicodeCategory.UppercaseLetter, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
{ UnicodeCategory.DecimalDigitNumber, "0123456789" }
};
var encoded = input.ToUpperInvariant()
.Select(c => new { Alphabet = classAlphabets[Char.GetUnicodeCategory(c)], Character = c })
.Select(x => new { x.Alphabet, Index = x.Alphabet.IndexOf(x.Character) })
.Select(x => new { x.Alphabet, Index = x.Index + shift })
.Select(x => new { x.Alphabet, Index = x.Index % x.Alphabet.Length })
.Select(x => x.Alphabet.ElementAt(x.Index))
.Aggregate(new StringBuilder(), (builder, character) => builder.Append(character))
.ToString();
Console.Write(encoded);
// encoded = "KHOOR ZRUOG 901"
Decoding is simply a case of inverting the shift.
Caesar cipher can be easier like this:
static char Encrypt(char ch, int code)
{
if (!char.IsLetter(ch))
{
return ch;
}
char offset = char.IsUpper(ch) ? 'A' : 'a';
return (char)(((ch + code - offset) % 26) + offset);
}
static string Encrypt(string input, int code)
{
return new string(input.ToCharArray().Select(ch => Encrypt(ch, code)).ToArray());
}
static string Decrypt(string input, int code)
{
return Encrypt(input, 26 - code);
}
const string TestCase = "Pack my box with five dozen liquor jugs.";
static void Main()
{
string str = TestCase;
Console.WriteLine(str);
str = Encrypt(str, 5);
Console.WriteLine("Encrypted: {0}", str);
str = Decrypt(str, 5);
Console.WriteLine("Decrypted: {0}", str);
Console.ReadKey();
}

How to read values from dictionary value collection and make it comma seperated string?

I have a dictionary object as under
Dictionary<string, List<string>> dictStr = new Dictionary<string, List<string>>();
dictStr.Add("Culture", new List<string>() { "en-US", "fr-FR" });
dictStr.Add("Affiliate", new List<string>() { "0", "1" });
dictStr.Add("EmailAddress", new List<string>() { "sreetest#test.com", "somemail#test.com" });
And I have an entity as under
public class NewContextElements
{
public string Value { get; set; }
}
What I need to do is that for every value in a particular index of the dictionary value collection, I have to make a comma separated string and place it into List collection.
e.g. the NewContextElements collection will have (obviously at run time)
var res = new List<NewContextElements>();
res.Add(new NewContextElements { Value = "en-US" + "," + "0" + "," + "sreetest#test.com" });
res.Add(new NewContextElements { Value = "fr-FR" + "," + "1" + "," + "somemail#test.com" });
I was trying as
var len = dictStr.Values.Count;
for (int i = 0; i < len; i++)
{
var x =dictStr.Values[i];
}
no it is of-course not correct.
Help needed
Try this:
Enumerable.Range(0, len).Select( i =>
new NewContextElements {
Value = string.Join(",", dictStr.Values.Select(list => list[i]))
}
);
len is the number of items inside the individual lists (in your example, it's two).
This isn't a slick as #dasblinkenlight's solution, but it should work:
Dictionary<string, List<string>> dictStr = new Dictionary<string, List<string>>( );
dictStr.Add( "Culture", new List<string>( ) {"en-US", "fr-FR"} );
dictStr.Add( "Affiliate", new List<string>( ) {"0", "1"} );
dictStr.Add( "EmailAddress", new List<string>( ) {"sreetest#test.com", "somemail#test.com"} );
int maxValues = dictStr.Values.Select(l => l.Count).Max();
List<NewContextElements> resultValues = new List<NewContextElements>(dictStr.Keys.Count);
for (int i = 0; i < maxValues; i++) {
StringBuilder sb = new StringBuilder();
string spacer = string.Empty;
dictStr.Keys.ForEach( k => {
sb.AppendFormat( "{0}{1}", spacer, dictStr[k][i] );
spacer = ", ";
} );
resultValues.Add( new NewContextElements( ){ Value = sb.ToString() });
}
do you mean transform your data like
1 2
3 4
5 6
to
1 3 5
2 4 6
try this block of code? it can be optimized in a few ways.
var res = new List<NewContextElements>();
int i = dictStr.values.count()
for (int i=0; i < len; i++) {
NewContextElements newContextElements = new NewContextElements();
foreach (List<string> list in dictStr) {
if (newContextElements.value() == null ) {
newContextElements.value = list[i];
} else {
newContextElements.value += ", " + list[i] );
}
}
res.add(newContextElements);
}
let me know if there are problems in the code, most like there is when you write it without a real ide.

Resources