2

I created a program that checks how many times an item is repeated in an array.

However, for every item that repeats at least twice, I want to assign it to a variable. My problem is that, my list might be bigger at times or smaller. So I need my loop to go through and if a copy is found, to create a variable of type int and assign the number of repeats to it. I seem to remember reading something on Java about this, but I forgot what it's called, or I'm just confused. Please help. Thank you.

Update: I want the output to be like this:

(A : 20) - (B : 114) - (C : 50) - (W : 0)

Currently I am trying to check if

    string[] art = new string[] {"ABAR 200", "CDXE 500", "BKWR 250", "BTSQ 890", "DRTY 600"};
    string[] cd = new string[] {"A", "B"};

    int control = 0;

    //I will fill this in the first loop below with 
    //the first letter of each item in the art array
    ArrayList firstLetter = new ArrayList ();

    //this one gets filled after the second loop ends
    ArrayList numOfLetters = new ArrayList ();

    for(int k = 0; k < art.Length; k++){ //iterate 4 times, add 1st letter
        firstLetter.Add (art[k].Substring(0, 1));
    }

    for (int j = 0; j < art.Length; j++) { //iterate 4 times 
        //check how many times a letter repeats in 'art'
        while (firstLetter.Contains (art [j].Substring (0, 1))) {
            control++; //
    }
        numOfLetters.Add ("(" + art [j].Substring (0, 1) + " " + ":" + " " + 
                control + ")");
            control = 0;
        }
    print (numOfLetters[0]);

If none of this makes sense, I would be happy to just know how I can check an arraylist for how many times a letter repeats.

i,e;

ArrayList A B C A D A E F

I want to know how I can check how many times 'A' repeats

1
  • 2
    You will probably want to use a List<int>. Commented Apr 10, 2015 at 5:51

3 Answers 3

2

I'm not quite sure what that block of code is doing, so I'll just address your last example. First, avoid using ArrayList. You can store any object in it, but you can't easily tell what type of object is stored in it. When you get the values back out, you have to unbox them. It's a pain to use.

Instead, use a List<T> where T is a string in your sample.

List<string> letters = new List<string> {"A", "B", "C", "A", "D", "A", "E", "F"};

Group your original array by values using LINQ (letters in your case), then store the count of any values that occur at least twice. (I modified your sample collection to have more duplicates.)

There's another built in method called string.Join, which takes a collection, flattens it out to a single string, and separates all the elements of the collection by some other string (" - " here).

var letters = new List<string> {"B", "A", "C", "A", "A", "B", "A", "B"};

var repeats = letters.GroupBy(i => i)
                     .Where(g => g.Count() >= 2)
                     .ToDictionary(t => t.Key, t => t.Count());

var output = string.Join(" - ", repeats.OrderBy(x => x.Key)
                                       .Select(x => string.Format("({0} : {1})", x.Key, x.Value)));

// output: "(A : 4) - (B : 3)"
Sign up to request clarification or add additional context in comments.

Comments

1

It sounds like you might be looking for a Dictionary<T, int>. You didn't mention what type of items are contained in the array, so you'll want to swap out the T with whatever that type is.

A quick and dirty implementation might look something like this:

Dictionary<object, int> dict = new Dictionary<object, int>();
object[] objs = new object[] { ... };

for (int v = 0; v < objs.Length; v++)
{
    object obj = objs[v];

    int count = dict.TryGet(obj, out count) ? count : 0;
    dict[obj] = count + 1;
}

This sounds like CS homework, so I'm assuming that's probably what you're looking for, but if this is for production, I'd be tempted to do it with LINQ.

Dictionary<object, int> dict = objs.GroupBy(c => c)
                                   .ToDictionary(c => c.Key, c => c.Count());

Once you've got your dictionary, it's just a matter of checking for items with more than one as the value. You can do that by looping through, either with a foreach or, again, with LINQ.

This is another super quick implementation, and you might want to do it differently. But this would capture the gist of it.

foreach (var v in dict.ToList())
{
    if (v.Value < 2)
        dict.Remove(v.Key);
}

Another feasible approach would be to make use of a HashSet<>, which only allows one instance of any given object at a time.

object[] objs = new object[] { ... };
HashSet<object> buffer = new HashSet<object>();
HashSet<object> repeated = new HashSet<object>();

foreach (var v in objs)
{
    if(!buffer.Add(v))
    {
        repeated.Add(v);
    }
}

Here, I loop through each item and add it to a buffer HashSet<>. If that returns false, it means it's already been added, so it's a duplicate. At that point, I append it to yet a second HashSet<>, which would be your result. I chose this over a List<> for the result because I assume you don't want duplicate reports in that, in the event of an item showing up in the array more than two times. But either works, aside from that.

Comments

0

Your item class:

class YourItem
{
    public int ItemId { get; set; }
    public string ItemName { get; set; }
}

Now in we fill in some list of items and process it:

// defining example item list
var items = new List<YourItem>() { 
    new YourItem() { ItemId = 1, ItemName = "FirstItem" }, 
    new YourItem() { ItemId = 1, ItemName = "FirstItem" }, 
    new YourItem() { ItemId = 2, ItemName = "SecondItem" } };

var groups = items.GroupBy(item => item.ItemId) // grouping your items by id (or how do you compare them?) to be able to count repetitions
    .Where(group => group.Count() > 1) // filtering out those that are not repeated
    .Select(group => new { Item = group.First(), Sum = group.Count() }); // selecting Item and Count for each group.

// processing the results
foreach (var group in groups)
{
    Console.WriteLine(group.Item.ItemName + " " + group.Sum);
}

Output:

FirstItem 2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.