I have an array list of List<string> that contains values in the following order ["1m", "1cm", "4km","2cm"] (Centimeters, meters and kilometers)
When I want to sort this array, I get a wrong answer. I use OrderBy:
List<string> data = new List<string> { "1m", "1cm", "4km","2cm" };
var result= data.OrderBy(x => x).ToList();
the result is:
{ "1cm", "1m", "2cm", "4km"}
But I want the answer to be this order-: { "1cm", "2cm", "1m", "4km"}
You have sorted the data alphabetically. First the first character is compared. Then the second character and...
You need to normalize the data based on cm(or m) and then sort.
List<string> data = new List<string> { "1m", "1cm", "4km","2cm" };
var result = data.OrderBy(x => lenghtCM(x));
public int lenghtCM(string lenghtStr)
{
if (lenghtStr.Contains("cm"))
{
string num = lenghtStr.Split("cm")[0];
return int.Parse(num);
}
else if (lenghtStr.Contains("km"))
{
string num = lenghtStr.Split("km")[0];
return int.Parse(num) * 100*1000;
}
else if (lenghtStr.Contains("m"))
{
string num = lenghtStr.Split('m')[0];
return int.Parse(num) * 100;
}
return 0;
}
then the result:
{ "1cm", "2cm", "1m", "4km"}
private string[] normalaizeArray(string[] inputArray)
{
for (int i= 0 ; i < inputArray.Length; i++)
{
if(inputArray[i].Contains('m'))
{
inputArray[i] = (float.Parse(inputArray[i].Split('k')[0]) * 100).ToString();
} else if(inputArray[i].Contains('km'))
{
inputArray[i] = (float.Parse(inputArray[i].Split('k')[0]) * 100*1000).ToString();
}
else
{
inputArray[i] = inputArray[i].Replace("cm", "");
}
}
inputArray = inputArray.OrderBy(x => int.Parse(x)).ToArray();
for (int i = 0; i < inputArray.Length; i++)
{
if(int.Parse(inputArray[i])>1000*100)
inputArray[i] = (float.Parse(inputArray[i])/1000).ToString() + "km";
else if(int.Parse(inputArray[i])>100)
inputArray[i] = (float.Parse(inputArray[i])/100).ToString() + "m";
else
inputArray[i] = inputArray[i] + 'cm';
}
return inputArray;
}
If you can, parse the strings first:
enum Unit { cm, m, km }
record Measurment(int Length, Unit Unit)
{
public override string ToString() => $"{Length}{Enum.GetName(typeof(Unit), Unit)}";
public double NormalizedLength => Unit switch
{
Unit.cm => Length * 0.001,
Unit.m => Length * 1.0,
Unit.km => Length * 1000.0,
_ => throw new NotImplementedException()
};
public static Measurment Parse(string source)
{
var digits = source.TakeWhile(char.IsDigit).Count();
var length = int.Parse(source.AsSpan(0, digits));
// switches with source.AsSpan(digits) in preview
var measure = source[..digits] switch
{
"cm" => Unit.cm,
"m" => Unit.m,
"km" => Unit.km,
_ => throw new NotImplementedException(),
};
return new Measurment(length, measure);
}
}
.
var result = data.Select(Measurment.Parse).OrderBy(x => x.NormalizedLength).ToList();
This lets you sort your measurments by NormalizedLength and ToString gets back the original string. Should be very fast, simple to extend with new units and you can make it fault-tolerant if you turn Parse into the TryParse pattern.
There's a NuGet package to manage parsing and manipulating SI units called UnitsNet.
If you install that package (via Add | NuGet Package, search for and select UnitsNet and install it), then you can write the following code:
(You'll need to add using UnitsNet; at the top of the code file first)
This also works with nm etc.
List<string> data = new List<string> { "1m", "1cm", "4km", "2cm" };
var result = data.OrderBy(Length.Parse).ToList();
Console.WriteLine(string.Join(", ", result));
This will output "1cm, 2cm, 1m, 4km"
You need custom sort using IComparable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication49
{
class Program
{
static void Main(string[] args)
{
List<string> data = new List<string> { "1m", "1cm", "4km", "2cm" };
List<string> results = data.Select(x => new SortDistance(x)).OrderBy(x => x).Select(x => x.value).ToList();
}
}
public class SortDistance : IComparable<SortDistance>
{
const string pattern = #"(?'number'\d+)(?'multiplier'.*)";
List<string> distanceOrder = new List<string>() { "cm", "m", "km" };
public string value { get; set; }
public int distance { get; set; }
public string multiplier { get; set; }
public SortDistance(string value)
{
this.value = value;
Match match = Regex.Match(value, pattern);
this.distance = int.Parse(match.Groups["number"].Value);
this.multiplier = match.Groups["multiplier"].Value;
}
public int CompareTo(SortDistance other)
{
if (this.multiplier == other.multiplier)
return this.distance.CompareTo(other.distance);
else
return distanceOrder.IndexOf(this.multiplier).CompareTo(distanceOrder.IndexOf(other.multiplier));
}
}
}
you can not sort using OrderBy.
You have to define the conversion first from all units to the smallest unit. for example m to cm, km to cm.....
so 1m euqals to 100 cm
then you have to iterate through your list and check each item's unit, get its equivalent to the smallest unit.
Create another list.
you can implement insertion sort to sort the items and add keep on inserting the item based on the comparison.
Related
I would like to ask you if there's a way by Linq to check discontinuity of multiple ranges, for example we have a class AgeRange:
public class AgeRange
{
public int firstValue {get;set;}
public int secondValue {get;set;}
}
var ageRange1 = new AgeRange(0,2); // interval [0,2]
var ageRange2 = new AgeRange(4,10); // interval [4,10]
var ageRange3 = new AgeRange(11,int.MaxValue); // interval [11,+oo[
var ageRangeList = new List<AgeRange>();
ageRangeList.Add(ageRange1);
ageRangeList.Add(ageRange2);
ageRangeList.Add(ageRange3);
in this example we have a discontinuity between first range and second range.
is there a way in Linq to check discontinuity between elements in ageRangeList ?
Thanks for you help.
Assuming firstValue always <= secondValue (for the same element), you can try to use Aggregate:
var start = ageRangeList
.OrderBy(a => a.firstValue).Dump()
.First();
var result = ageRangeList
.OrderBy(a => a.firstValue)
.Aggregate(
(hasGap: false, s: start.secondValue),
(tuple, range) =>
{
if (tuple.hasGap)
{
return tuple;
}
else
{
var max = Math.Max(tuple.s, tuple.s+1); //hacky overflow protection
if (max < range.firstValue)
{
return (true, tuple.s);
}
else
{
return (false, Math.Max(tuple.s, range.secondValue));
}
}
})
.hasGap;
The downside of such approach is that it still will need to loop through all age ranges.
If you want to find first discontinuity and use that information elsewhere
public static IEnumerable<AgeRange> FindDiscontinuity(List<AgeRange> ageRangeList) {
foreach(var ageRange in ageRangeList.Zip(ageRangeList.Skip(1), (a, b) => new {Prev = a, Current = b})) {
if(ageRange.Prev.SecondValue != ageRange.Current.FirstValue) {
yield return ageRange.Prev;
yield return ageRange.Current;
break;
}
}
}
public static void Main()
{
var ageRange1 = new AgeRange(0, 2);
var ageRange2 = new AgeRange(4, 10);
var ageRange3 = new AgeRange(11, int.MaxValue);
var ageRangeList = new List<AgeRange>();
ageRangeList.Add(ageRange1);
ageRangeList.Add(ageRange2);
ageRangeList.Add(ageRange3);
var result = FindDiscontinuity(ageRangeList);
foreach(var ageRange in result) {
Console.WriteLine("{0}, {1}", ageRange.FirstValue, ageRange.SecondValue);
}
}
You can change the function so it can return boolean value instead of data.
Need suggestions on how to order the strings in order in a linq query.
Example of strings in db [1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 2.1a(i) 2.1a(ii) 2.1a(iii) 2.1a(iv) 2.1a(v) 2.1a(vi) 2.1a(vii) , ....]
In order to solve the issue for a job case.
I have written a linq query which suppose to order the jobs based on band level
var GetOrder =(from a in db.Details
join b in db.Information on a.InfromationId equals b.Id
where c.JobId == JobId
select new {a.Name, a.LastName, b.BandLevel}
//.OrderBy(b=>b.BandLevel)
.ToList();
I added the below query for it can order and sort for strings.
GetOrder.Sort((a, b) => a.BandLevel.CompareTo(b.BandLevel));
This query is suppose to sort the stings in order but it fails to set for some strings.
Instead it orders in this format using the above query.
1.1 , 1.10, 1.19 ,1.2, 2.1a(i) ,2.21(v)
It should be in this desired list .
1.1 ,1.2, 1.10, 1.19 , 2.1a(i) ,2.21(v)
Any suggestions on how to sort it in the suggested order for linq queries.
Well, p.s.w.g has a great answer, but since I worked on this a little I figured I would post mine as well.
My suggestion is to create a class that encapsulates the data from the string, which can only be instantiated from a static Parse method. This Parse method takes in a string and then parses it, setting the properties of the class as it does, and then returns the instance of the class.
The class also implements IComparable, so we can use the Sort and OrderBy methods on a list of these items.
I also used the same answer for parsing roman numerals that was used above (it's the first result when searching for "roman numeral comparer").
Here's the class:
public class BandLevelComponent : IComparable<BandLevelComponent>
{
public int Major { get; private set; }
public int Minor { get; private set; }
public string Revision { get; private set; }
public string RomanNumeral { get; private set; }
private static Dictionary<char, int> _romanMap = new Dictionary<char, int>
{
{'I', 1},
{'V', 5},
{'X', 10},
{'L', 50},
{'C', 100},
{'D', 500},
{'M', 1000}
};
private BandLevelComponent()
{
}
public static BandLevelComponent Parse(string input)
{
if (string.IsNullOrWhiteSpace(input)) return null;
BandLevelComponent result = new BandLevelComponent();
int temp;
var parts = input.Split('.');
int.TryParse(parts[0], out temp);
result.Major = temp;
if (parts.Length > 1)
{
var minor = string.Concat(parts[1].TakeWhile(char.IsNumber));
int.TryParse(minor, out temp);
result.Minor = temp;
if (parts[1].Length > minor.Length)
{
var remaining = parts[1].Substring(minor.Length);
var openParen = remaining.IndexOf("(");
if (openParen > 0) result.Revision = remaining.Substring(0, openParen);
if (openParen > -1)
result.RomanNumeral = remaining
.Split(new[] {'(', ')'}, StringSplitOptions.RemoveEmptyEntries)
.Last();
}
}
return result;
}
public int CompareTo(BandLevelComponent other)
{
if (other == null) return 1;
if (Major != other.Major) return Major.CompareTo(other.Major);
if (Minor != other.Minor) return Minor.CompareTo(other.Minor);
if (Revision != other.Revision) return Revision.CompareTo(other.Revision);
return RomanNumeral != other.RomanNumeral
? RomanToInteger(RomanNumeral).CompareTo(RomanToInteger(other.RomanNumeral))
: 0;
}
public override string ToString()
{
var revision = Revision ?? "";
var roman = RomanNumeral == null ? "" : $"({RomanNumeral})";
return $"{Major}.{Minor}{revision}{roman}";
}
private static int RomanToInteger(string romanNumeral)
{
var roman = romanNumeral?.ToUpper();
var number = 0;
for (var i = 0; i < roman?.Length; i++)
{
if (i + 1 < roman.Length && _romanMap[roman[i]] < _romanMap[roman[i + 1]])
{
number -= _romanMap[roman[i]];
}
else
{
number += _romanMap[roman[i]];
}
}
return number;
}
}
And here's a sample usage:
private static void Main()
{
var dbStrings = new[]
{
"1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11",
"1.12", "1.13", "1.14", "1.15", "1.16", "1.17", "1.18", "1.19", "1.20", "2.1a(i)",
"2.1a(ii)", "2.1a(iii)", "2.1a(iv)", "2.1a(v)", "2.1a(vi)", "2.1a(vii)"
};
// Custom extension method for shuffling
dbStrings.Shuffle();
// Select each string into our custom class
var bandLevels = dbStrings.Select(BandLevelComponent.Parse).ToList();
Console.WriteLine("\nShuffled List");
Console.WriteLine(string.Join(", ", bandLevels));
// Sort the list
bandLevels.Sort();
Console.WriteLine("\nSorted List");
Console.WriteLine(string.Join(", ", bandLevels));
// Order the list descending (largest first)
bandLevels = bandLevels.OrderByDescending(b => b).ToList();
Console.WriteLine("\nOrderByDescending List");
Console.WriteLine(string.Join(", ", bandLevels));
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output
Here's my stab at it. First split the string into various parts, e.g. 2.11a(ii) will become 2, 11, a, and ii. The first two parts can be parsed as regular integers. The second part is parsed as a integer with a=1, b=2 and so on. The third part is parsed as a Roman numeral (I used a modified version of the algorithm presented in this answer). You collect these parts as an array of integers (I call them indexes), and compare the array from one item to the next such that if the first index of each is equal, the items are equal, and so on until an index is unequal.
public static int CustomComparison(string x, string y)
{
var xIndexes = StringToIndexes(x);
var yIndexes = StringToIndexes(y);
for (int i = 0; i < 4; i++)
{
if (xIndexes[i] < yIndexes[i])
{
return -1;
}
if (xIndexes[i] > yIndexes[i])
{
return 1;
}
}
return 0;
}
private static int[] StringToIndexes(string input) {
var match = Regex.Match(input, #"^(\d+)\.(\d+)([a-z]+)?(?:\(([ivx]+)\))?$");
if (!match.Success)
{
return new[] { 0, 0, 0, 0 };
}
return new[] {
int.Parse(match.Groups[1].Value),
int.Parse(match.Groups[2].Value),
AlphabeticToInteger(match.Groups[3].Value),
RomanToInteger(match.Groups[4].Value),
};
}
private static int AlphabeticToInteger(string alpha)
{
return alpha.Aggregate(0, (n, c) => n * 26 + (int)(c - 'a' + 1));
}
private static Dictionary<char, int> RomanMap = new Dictionary<char, int>()
{
{'i', 1},
{'v', 5},
{'x', 10},
};
public static int RomanToInteger(string roman)
{
int number = 0;
for (int i = 0; i < roman.Length; i++)
{
if (i + 1 < roman.Length && RomanMap[roman[i]] < RomanMap[roman[i + 1]])
{
number -= RomanMap[roman[i]];
}
else
{
number += RomanMap[roman[i]];
}
}
return number;
}
I have a List where each double[] has a length of 3. I would like to clean this list by leaving only those double[] having unique elements within a given tolerance (round up). For instance, a list like the one below:
1059.17 0 446.542225842081
1059.17 0 446.542564789741
1059.17 0 446.541759880305
959.167 0 579.827860527898
959.167 0 579.827847296075
Should become this for a given tolerance=two:
1059.17 0 446.54,
959.17 0 579.83,
Is there a smart way to do this in a neat way?
This should work. It uses the build-in equality comparisons of anonymous types.
List<double[]> data = ...
int tolerance = 2;
var roundedData = data
.Select(x => new {
v1 = Math.Round(x[0], tolerance),
v2 = Math.Round(x[1], tolerance),
v3 = Math.Round(x[2], tolerance)
})
.Distinct()
.Select(x => new [] { x.v1, x.v2, x.v3 })
.ToList();
Providing that array elements are always in the same order you can create your own comparer that should know how to compare double arrays :
public class MyDoubleArrComparer : IEqualityComparer<double[]>
{
public bool Equals(double[] x, double[] y)
{
for (int i = 0; i < x.Length; i++)
{
if (x[i] != y[i]) return false;
}
return true;
}
public int GetHashCode(double[] obj)
{
return base.GetHashCode();
}
}
And you can create a helper method that will round numbers and remove duplicates :
public static class Helper
{
public static List<double[]> MyFilter(this List<double[]> list, int tolerance)
{
var result = list
.Select(arr =>
{
// rounds numbers with precision that is set in tolerance variable
arr = arr.Select(d => d = Math.Round(d, tolerance)).ToArray();
return arr;
}).Distinct(new MyDoubleArrComparer()) // here we use our custom comparer
.ToList();
return result;
}
}
Now we can start using our helper method :
var nums = new List<double[]>()
{
new[] {1059.17, 0, 446.542225842081},
new[] {1059.17, 0, 446.542564789741},
new[] {1059.17, 0, 446.541759880305},
new[] {959.167, 0, 579.827860527898},
new[] {959.167, 0, 579.827847296075},
};
var result = nums.MyFilter(2);
foreach (var arr in result)
{
foreach (var d in arr)
{
Console.Write(d + " ");
}
Console.WriteLine();
}
Output :
1059.17 0 446.54
959.17 0 579.83
Maybe this will work?
public List<double[]> CleanWithTolerance(List<double[]> doubleNumbersList, int tolerance)
{
var newDoublesNumbersList = new List<double[]>();
foreach(double[] doubleNumbers in doubleNumbersList)
{
var newDoublesNumbers = doubleNumbers.Select(doubleNumber => Math.Round(doubleNumber, tolerance)).ToArray();
if(newDoublesNumbersList.All(cleanDoubleNumbers => !Enumerable.SequenceEqual(cleanDoubleNumbers, newDoublesNumbers))
{
newDoublesNumbersList.Add(newDoublesNumbers);
}
}
return newDoublesNumbersList;
}
I have some strings in a list
List<string> list = new List<string>{ "100-1", "100-11", "100-3", "100-20" }
I used following code to sort which is picked from this location
void Main()
{
string[] things= new string[] { "100-1", "100-11", "100-3", "100-20" };
foreach (var thing in things.OrderBy(x => x, new SemiNumericComparer()))
{
Console.WriteLine(thing);
}
}
public class SemiNumericComparer: IComparer<string>
{
public int Compare(string s1, string s2)
{
if (IsNumeric(s1) && IsNumeric(s2))
{
if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 1;
if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return -1;
if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return 0;
}
if (IsNumeric(s1) && !IsNumeric(s2))
return -1;
if (!IsNumeric(s1) && IsNumeric(s2))
return 1;
return string.Compare(s1, s2, true);
}
public static bool IsNumeric(object value)
{
try {
int i = Convert.ToInt32(value.ToString());
return true;
}
catch (FormatException) {
return false;
}
}
}
My output is 100-1, 100-11, 100-20, 100-3
I believe it is taking - as decimal and comparing the values. Actually I was expecting the result to be
100-1, 100-3, 100-11, 100-20.
I just wanted to know on what basis it is actually performing sort. Any help is appreciated. Even I expect it to treat 100-2 and 100-20 differently.
Just on the fly, I have seen in Infragistic control grid that sorting in it produces the same result as I was expecting here to be.
I have many other string values in the list, some are integers, doubles and so on. Hyphen is just a case mentioned here.
var sorted = things.Select(s => s.Split('-'))
.OrderBy(x => double.Parse(x[0]))
.ThenBy(x => double.Parse(x[1]))
.Select(x=>String.Join("-",x))
.ToList();
This should work as expected:
string[] things= new string[] { "100-1", "100-11", "100-3", "100-20" };
IEnumerable<string> ordered = things
.Select(s => new
{
str = s,
firstPart = s.Split('-').ElementAtOrDefault(0),
secondPart = s.Split('-').ElementAtOrDefault(1)
})
.OrderBy(x => int.Parse(x.firstPart))
.ThenBy(x => int.Parse(x.firstPart))
.Select(x => x.str);
foreach (string s in ordered)
Console.WriteLine(s);
Although it assumes that your data is strict, otherwise you're open for exceptions, f.e at int.Parse(x.firstPart).
Demo: http://ideone.com/UJ5Yt4
If you want to sort the items by the 2nd number (after hyphen), You need to parse the string to a number then order by using it. you can try:
string[] things = new string[] { "100-1", "100-11", "100-3", "100-20" };
var test = things.OrderBy(r => int.Parse(r.Split('-')[1])).ToArray();
The reason your current code is not working is probably due to the fact that it can't parse the string 100- to an integer value and your function IsNumeric is returning false.
First of all sorry for my mistakes in English its not my primary language
i have a problem , i have a array like following
string[] arr1 = new string[] {
"Pakistan:4,India:3,USA:2,Iran:1,UK:0",
"Pakistan:4,India:3,USA:2,Iran:1,UK:0",
"India:4,USA:3,Iran:2,UK:1,Pakistan:0"
};
now i just want to know that how many times Pakistan comes with 1 ,
how many times with 2 , 3 , 4
and i need to know this about all India , USA , Iran , UK
Thanks in advance , you guys are my last hope .
This linq will convert the array into a Dictionary>, where the outer dictionary contains the countries names, and inner dictionaries will contain the ocurrence number (the number after ':') and the count for each ocurrence.
string[] arr1 = new string[]
{
"Pakistan:4,India:3,USA:2,Iran:1,UK:0",
"Pakistan:4,India:3,USA:2,Iran:1,UK:0",
"India:4,USA:3,Iran:2,UK:1,Pakistan:0"
};
var count = arr1
.SelectMany(s => s.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
.GroupBy(s => s.Split(':')[0], s => s.Split(':')[1])
.ToDictionary(g => g.Key,
g =>
{
var items = g.Distinct();
var result = new Dictionary<String, int>();
foreach (var item in items)
result[item] = g.Count(gitem => gitem == item);
return result;
});
// print the result
foreach(var country in count.Keys)
{
foreach(var ocurrence in count[country].Keys)
{
Console.WriteLine("{0} : {1} = {2}", country, ocurrence, count[country][ocurrence]);
}
}
I would use the String.Split(char[]) method and the String.SubString(int, int) method to inspect every 'country' inside your array and to get the number postfix of each country.
Try the following:
(The following code is now compiled and tested.)
Use a simple data structure to facilitate the task of holding the result of your operation.
public struct Result {
string Country { get; set; }
int Number { get; set; }
int Occurrences { get; set; }
}
// define what countries you are dealing with
string[] countries = new string[] { "Pakistan", "India", "USA", "Iran", "UK", }
Method to provide the overall result:
public static Result[] IterateOverAllCountries () {
// range of numbers forming the postfix of your country strings
int numbersToLookFor = 4;
// provide an array that stores all the local results
// numbersToLookFor + 1 to respect that numbers are starting with 0
Result[] result = new Result[countries.Length * (numbersToLookFor + 1)];
string currentCountry;
int c = 0;
// iterate over all countries
for (int i = 0; i < countries.Length; i++) {
currentCountry = countries[i];
int j = 0;
// do that for every number beginning with 0
// (according to your question)
int localResult;
while (j <= numbersToLookFor) {
localResult = FindCountryPosition(currentCountry, j);
// add another result to the array of all results
result[c] = new Result() { Country = currentCountry, Number = j, Occurrences = localResult };
j++;
c++;
}
}
return result;
}
Method to provide a local result:
// iterate over the whole array and search the
// occurrences of one particular country with one postfix number
public static int FindCountryPosition (string country, int number) {
int result = 0;
string[] subArray;
for (int i = 0; i < arr1.Length; i++) {
subArray = arr1[i].Split(',');
string current;
for (int j = 0; j < subArray.Length; j++) {
current = subArray[j];
if (
current.Equals(country + ":" + number) &&
current.Substring(current.Length - 1, 1).Equals(number + "")
)
result++;
}
}
return result;
}
The following should enable you to run the algorithm
// define what countries you are dealing with
static string[] countries = new string[] { "Pakistan", "India", "USA", "Iran", "UK", };
static string[] arr1 = new string[] {
"Pakistan:4,India:3,USA:2,Iran:1,UK:0",
"Pakistan:4,India:3,USA:2,Iran:1,UK:0",
"India:4,USA:3,Iran:2,UK:1,Pakistan:0"
};
static void Main (string[] args) {
Result[] r = IterateOverAllCountries();
}
The data structure you are using is not rich enough to provide you with that information. Hence you need to parse your string and create a new data structure to be able to provide (sring[][]):
string[] arr1 = new string[] {
"Pakistan,India,USA,Iran,UK",
"Pakistan,India,USA,Iran,UK",
"India,USA,Iran,UK,Pakistan"
};
string[][] richerArray = arr1.Select(x=> x.Split('\'')).ToArray();
var countPakistanIsFirst = richerArray.Select(x=>x[0] == "Pakistan").Count();
UPDATE
You seem to have changed your question. The answer applies to the original question.