-1

everyone. Very first question, so take it easy on this noob. ;)

Anyway, really stumped on something. I've got a text file with this sort of listing:

1: A C D
4: A B
5: D F
7: A E
9: B C

The goal is to somehow re-sort this list and have it appear as this:

A: 1 4 7
B: 4 9
C: 1 9
D: 1 5
E: 7
F: 5

The trick is matching and displaying those matched values. For example "A" is matched with lines 1,4 and 7, and so on. I can explode the lines into individual arrays, but after that stumps me. How would I go about taking those arrays and somehow sorting them out to make it look like the final version?

Thanks for any and all info!

UPDATE:

Code I have so far:

<?php
$string="1: A C D
4: A B
5: D F
7: A E
9: B C";
$lines = explode( "\n", $string );
sort($lines);
foreach($lines as $line){
echo $line."<br>";
}

// start with this
//1: A C D
//4: A B
//5: D F
//7: A E
//9: B C

// resort and display as this
//A: 1 4 7
//B: 4 9
//C: 1 9
//D: 1 5
//E: 7
//F: 5
?>

Which produces:

1: A C D
4: A B
5: D F
7: A E
9: B C

Right now I don't care that they are not in new lines. That's not important at the moment. Right now, I need to figure out how to make it sort and appear as the 2nd code block. That is the part that puzzles me.

Hope this helps clear up things.

syntonik
  • 3
  • 2
  • explain better what you want to be done. You said A is matched with lines 1,4 and 7, however then for some reason the 1 became an A, an extra line was included in the new text file, you replaced 2 of the 'A's with 1s and only 1 of the 'A's with 4. We can't help you answer the question if we don't know what you want done, and your question is missing too much information to know exactly what you want done. – Webeng May 05 '16 at 15:51
  • 2
    The example is pretty self-explantory – Michael Eugene Yuen May 05 '16 at 15:52
  • Sorry about that, it really is a complex request. In the first block, 1 has three letters in it: A, C, D. 2 has A and B, and so on. The request is to pretty much count what lines "A" appears in, and display it as shown in the 2nd code block. So, for example, "A" shows up in lines 1, 4, and 7, but delimited using spaces, for some reason. Hope that clears any confusion up. – syntonik May 05 '16 at 15:53
  • 1
    As @MichaelEugeneYuen said, the example is quite clear. Can you share your code, please? – Jordi Nebot May 05 '16 at 16:08
  • 1
    Many people here could do it, but the point of SO is to help people with their code, not to find someone to do your work. – Julie Pelletier May 05 '16 at 16:11
  • 1
    If you don't know how to start, take a look at [How to read a file line by line in PHP](http://stackoverflow.com/questions/13246597/how-to-read-a-file-line-by-line-in-php) and also to the [explode](http://php.net/manual/en/function.explode.php) and [implode](http://php.net/manual/en/function.implode.php) PHP functions. You could use them to transform your strings into arrays and manipulate them to get your expected output. This is just a _hint_ for a possible approach... If you get stuck, update your question with your code and we'll help you :) – Jordi Nebot May 05 '16 at 16:28
  • Start with this: $lines = " 1: A C D 4: A B 5: D F 7: A E 9: B C"; $first_array = explode("\n", $lines); preserve the line break like you example – Michael Eugene Yuen May 05 '16 at 16:41
  • @MichaelEugeneYuen - I updated the code snippet so that the exploded lines appeared better, and in the way the final result should appear. Thanks. ;) – syntonik May 05 '16 at 16:43
  • Then turn it line to array('1:','A','C','D') example – Michael Eugene Yuen May 05 '16 at 16:47
  • foreach ($first_array as $key =>$val) { $new_array = explode (' ',$val); unset ($new_array[0]) } – Michael Eugene Yuen May 05 '16 at 16:50
  • Gotta sleep. Should be enough for direction – Michael Eugene Yuen May 05 '16 at 16:53

4 Answers4

0

Well, you sort of gave it a try and I was bored:

//read file into array of lines
$lines = file('/path/to/file.txt', FILE_IGNORE_NEW_LINES);

//loop through the lines
foreach($lines as $line) {
    //explode on space
    $cols = explode(' ', $line);
    //loop through columns and build array with letter as key adding number to that array
    for($i=1; $i < count($cols); $i++) {
        $result[$cols[$i]][] = trim($cols[0], ':');
    }
}
//sort by key (or sort $output later)
ksort($result);

//loop through and build new lines
foreach($result as $key => $vals) {
    $output[] = "{$key}: " . implode(' ', $vals);
}
//write lines to file
file_put_contents('/path/to/file.txt', implode("\n", $output));
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • This got me to a good point to expand on. This was a lot more code than I thought would be needed, but it does work. Thank you! – syntonik May 05 '16 at 18:16
0

you can use fgets read line by line, and explode line to array. that is you have an array like:

$arr = array(
      1 =>['A', 'C', 'D'],
      4 => ['A', 'B'],
      5 => ['D', 'F'],
      7 => ['A', 'E'],
      9 => ['B', 'C']
   );

Then convert and sort it:

$converted = [];

foreach ($arr as $ind => $a) {
   foreach ($a as $e) {
      if (isset($converted[$e])) {
         $converted[$e][] = $ind; 
      } else {
         $converted[$e] = array($ind);
      }
   }
}

ksort($converted);

Finally, you may use implode to output each sub-array as a line.

0

This is what I did:

$lines = "
1: A C D
4: A B
5: D F
7: A E
9: B C
";

$first_array = explode("\n", $lines);
$new_order_key = array();
foreach ($first_array as $key =>$val) {
    $tmp_array  = explode (' ',$val);
    $key = str_replace(':', '', $tmp_array[0]);
    unset($tmp_array[0]); //remove the first line break
    $new_array[$key] = $tmp_array;
    $new_order_key = array_unique(array_merge($tmp_array, $new_order_key));
}
$new_array = array_filter($new_array);
$final_array = array();
foreach($new_order_key as $key=>$val) {
    foreach($new_array as $tmp_array_key => $temp_array_val) {
        foreach ($temp_array_val as $v) {
            if($val == $v) {
                $final_array[$val][] = $tmp_array_key;
            }
        }
    }
}
ksort($final_array);

foreach($final_array as $key=>$val) {
    echo $key.': '.implode(' ',$val).'<br />';
}

And I got this output:

A: 1 4 7
B: 4 9
C: 1 9
D: 1 5
E: 7
F: 5
Michael Eugene Yuen
  • 2,470
  • 2
  • 17
  • 19
0

Another implementation:

<?php
$handle = fopen( "input.txt", "r" );
while ( ( $line = fgets( $handle ) ) !== false ) {
    list( $index, $letters ) = explode( ": ", $line );
    $letters = explode( " ", $letters );
    foreach ( $letters as $letter ) {
        $group[ $letter ][] = $index;
    }
}
ksort($group);
foreach ( $group as $key => $values ) {
    $output[] = $key . ": " . implode( " ", $values );
}
file_put_contents( "output.txt", implode( "\n", $output ) );
Jordi Nebot
  • 3,355
  • 3
  • 27
  • 56