-2

I have an array like this:

$origen = ["dog","dog","dog","cat","cat","bear","bear","alien","mouse"];

I need to find the value which has the most consecutive occurrences and the number of occurrences of that value.

Most consecutively repeating value is: dog (3 times)

I thought that it could be done with array_count_values(), but that also counts non-consecutive values.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Jean
  • 13
  • 5
  • @Nytrix `array_count_values` doesn't account for the "consecutive" part, does it? – Don't Panic Feb 14 '17 at 19:48
  • 1
    What is the desired output for your input data? Do you need the value with most consecutive occurences or all values with consecutive occurences? – Jirka Hrazdil Feb 14 '17 at 19:51
  • 1
    What if it were `array('dog', 'mouse', 'dog', 'cat', 'cat');` You would not expect to see a count for dog then? – nerdlyist Feb 14 '17 at 19:51
  • @nerdlyist no only consecutive , for example this array : array('cat','cat','dog','dog','dog','bear','cat') , output : dog repited 3 times consecutive. – Jean Feb 14 '17 at 22:22
  • Based on your comment to @Don'tPanic what you state there is not accurate. Are looking for the number of repetitions or number of occurrence of repetition? – nerdlyist Feb 15 '17 at 13:17
  • number of occurrence of repetition. – Jean Feb 15 '17 at 20:14
  • Related page: https://stackoverflow.com/q/5255281/2943403 – mickmackusa Jun 13 '21 at 06:55

3 Answers3

2

array_count_values won't help you with this if keeping track of consecutive repetitions is important. You'll just have to loop over the array and compare each value to the previous value. If it matches, increment your "repeated" count for that word.

$origen = array("dog","dog","dog","cat","cat","bear","bear","alien","mouse");

$previous = null;
$repetitions = array();
foreach ($origen as $word) {
    if ($word == $previous) {
        if (!isset($repetitions[$word])) $repetitions[$word] = 1;
        $repetitions[$word]++;
    } 
    $previous = $word;
}
print_r($repetitions);

Output

Array ( [dog] => 3 [cat] => 2 [bear] => 2 )

Your comment was correct, the previous method only works if there is only one repeated set of any repeated words. If there can be more than one set (why now?) I came up with this:

First, separate the array of words into sub-arrays, separated by repeated sets.

$previous = null;
foreach ($origen as $word) {
    if ($word != $previous) {
        if (!empty($set)) $sets[] = $set;
        $set = [$word];
    } else {
        $set[] = $word;
    }
    $previous = $word;
}
if ($set) $sets[] = $set;

Then examine the sets and add up instances that have more than one item (consecutive repetitions of a word.)

foreach ($sets as $set) {
    if (count($set) > 1) {
        $key = reset($set);
        if (!isset($result[$key])) $result[$key] = 0;
        $result[$key] += count($set);
    }
}
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
  • no works in array like this : $origen = array("dog","dog","dog","cat","cat","bear","dog","dog","mouse"); output Array ( [dog] => 4 [cat] => 2 ) – Jean Feb 14 '17 at 22:40
  • @Jean That's certainly true, and a good point. I think I see how that could be handled, though. I'll edit the answer. – Don't Panic Feb 14 '17 at 22:42
  • thanks for the update , but the same resutl , output : Array ( [dog] => 5 [cat] => 2 ) – Jean Feb 15 '17 at 01:46
  • Oh, I thought that's what it should be. What should it be? – Don't Panic Feb 15 '17 at 01:47
  • Well, let's look at this array $array = array ("x","x","x","a","b","x","x","x","x","c","x","x","x","x","x") The x is repeated 5 times consecutively. that is the result – Jean Feb 15 '17 at 02:37
  • Oh, so the maximum of consecutive repetitions for each word? – Don't Panic Feb 15 '17 at 02:39
  • I see. I'm not near a computer any more and can't write code well on my phone, but I'll make one more edit when I get back. Probably tomorrow, though. – Don't Panic Feb 15 '17 at 03:11
1

The solution using preg_match_all, array_combine and array_map functions:

$origen = ["dog","dog","dog","cat","cat","bear","bear","alien","mouse"];
$reps = [];
if (preg_match_all("/(\w+) (\\1\s?){1,}/", implode(" ", $origen), $matches)) {
    $reps = array_combine($matches[1], array_map(function($v){
        return count(explode(' ', trim($v)));
    }, $matches[0]));
}

print_r($reps);

The output:

Array
(
    [dog] => 3
    [cat] => 2
    [bear] => 2
)
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
-1

I probably shouldn't be using session variables for this, but:

session_start();
session_unset();

$_SESSION["counts"] = Array();

function value_count($s) {
     if (!isset($_SESSION[$s])) {
        $_SESSION[$s] = 1;
    } else {
        $_SESSION[$s] += 1;
    }

    if (!in_array($s, $_SESSION["counts"])) {
        array_push($_SESSION["counts"], $s);
    }

}

$origen = Array("dog","dog","dog","cat","cat","bear","b   ear","alien","mouse");

foreach ($origen as $value) {
    value_count($value);
}

foreach ($_SESSION["counts"] as $item) {
    echo $item . ": " . $_SESSION[$item] . "<br>";
}
cCe.jbc
  • 107
  • 1
  • 9
  • There is no reason to misuse/abuse a session variable here to get data in/out of the function scope AND using `in_array()` is one of the least efficient tools that can be used for this task. – mickmackusa Jun 02 '21 at 22:08