我可以将dirnames全局化到一个数组中,然后按文件值进行排序吗?


can i glob dirnames to an array and then usort by a file value?

谁能告诉我是否可以为usort编写一个函数,该函数将在PHP中执行以下操作:

首先,我有一堆目录,里面都有两个文件-这两个文件每个都包含一个数字作为纯文本

我想这样做:

将目录列表写入数组,调用$dirs

使用usort函数执行以下操作:

  1. 读取每个目录下的两个文件(file1.txt和file2.txt),并将它们相乘得到第三个数字$value
  2. 将原始$dirs数组按每个dir的$值降序排序。

好的,我可以像这样修改文件:

$dirs = glob('*',GLOB_NOSORT|GLOB_ONLYDIR); 

,我可以很容易地使用file_get_contents拉值,但我不知道如何将所有这些组合成usort的函数。

试试这个:

<?php
$dirs = array();
foreach (glob('*',GLOB_NOSORT|GLOB_ONLYDIR) as $dir) {
    $value = 
        (int)file_get_contents($dir.'/file1.txt') * 
        (int)file_get_contents($dir.'/file2.txt') ;
    $dirs[] = array(
        'path'  => $dir,
        'value' => $value,
    );
}
usort($dirs, function($a, $b) {
    return $b['value'] - $a['value'];
});

那么你想得到一维的结果,

$dirs = array_map(function ($dir) {
    return $dir['path'];
}, $dirs);

下面的代码片段可以做到这一点:

$dirs = glob('*',GLOB_NOSORT|GLOB_ONLYDIR); 
usort($dirs, function ($a, $b) {
    $val_a = $val_b = 1;
    foreach(scandir($a) as $file) {
        if(strpos($file, '.') === 0) {
            continue;
        }   
        $val_a *= intval(trim(file_get_contents($a. '/' . $file)));
    }   
    foreach(scandir($b) as $file) {
        if(strpos($file, '.') === 0) {
            continue;
        }   
        $val_b *= intval(trim(file_get_contents($b. '/' . $file)));
    }   
    if($val_a === $val_b) {
        return 0;
    } else if($val_a > $val_b) {
        return 1;
    } else {
        return -1; 
    }   
});
var_dump($dirs);

假设您使用的是5.3.0或更高版本,您可以使用匿名函数来完成此操作。下面您将看到函数buildSort,它返回一个函数对象(PHP称为"闭包",尽管在某些圈子中这个术语是否正确应用存在严重争议)。我们将使用它来"记忆"dir/file1.txt和dir/file2.txt的读取,以及数学运算,因此我们只需要在每个目录执行一次:

<?php
function buildSort(&$values) {
        return function ($a, $b) use(&$values) {
                if (!isset($values[$a])) {
                        $values[$a] = file_get_contents($a.'/file1.txt')*
                          file_get_contents($a.'/file2.txt');
                }
                if (!isset($values[$b])) {
                        $values[$b] = file_get_contents($b.'/file1.txt')*
                          file_get_contents($b.'/file2.txt');
                }
                return strcmp($values[$a], $values[$b]);
        };
}

$dirs = glob('*',GLOB_NOSORT|GLOB_ONLYDIR);
$values = array();
$sort = buildSort($values);
usort($dirs, $sort);
var_dump($dirs);

避免通过引用传递$值的答案留给读者作为练习。:)