【问题标题】:Compare & sort an array of objects against another array将一个对象数组与另一个数组进行比较和排序
【发布时间】:2017-04-27 04:57:12
【问题描述】:

我目前有一个对象数组,如下所示:

$aa = new StdClass;
$aa->name = 'aa';
$aa->index = 30;
$bb = new StdClass;
$bb->name = 'bb';
$bb->index = 30;
$cc = new StdClass;
$cc->name = 'cc';
$cc->index = 10;
$dd = new StdClass;
$dd->name = 'dd';
$dd->index = 20;
$ee = new StdClass;
$ee->name = 'ee';
$ee->index = 10;

我已将我的对象放入一个数组中进行排序:

$arr = [$aa, $bb, $cc, $dd];

我还有一个额外的数组,我想将其用于在索引处按顺序对对象进行排序,例如$aa->index:

$map = [30, 20, 10, 10, 30];

预期的结果是:

[$aa, $dd, $cc, $ee, $bb]

$aa$bb 中的另一个是未定义的,它们不能重复,所有索引都必须分配到某个地方。

按照$map 设置的顺序排列$arr 的最佳方式是没有使用foreach() 循环吗?

【问题讨论】:

  • 如何判断第一个索引 - 30 - 是指对象 $aa 还是 $bb
  • @JiriHrazdil 随机,我想
  • 举个例子 - [$aa, $dd, $cc, $cc, $aa] 是正确的输出吗?
  • 不,应该是 [$aa, $dd, $cc, $ee, $bb] 或者类似的。没有重复
  • 这不是重复的,在这种情况下使用 array_search 将不起作用,因为引用 $order(或在这种情况下为 $map)具有重复的值,来自原始数组的所有对象都具有相同的索引属性无论在 $order 或 $map 中的位置如何,都会一个接一个地排序。

标签: php arrays sorting


【解决方案1】:

老实说,我不确定我是否正确理解了这个问题,但这里尝试解决您的问题:

$aa = new stdClass;
$aa->name = 'aa';
$aa->index = 30;
$bb = new stdClass;
$bb->name = 'bb';
$bb->index = 30;
$cc = new stdClass;
$cc->name = 'cc';
$cc->index = 10;
$dd = new stdClass;
$dd->name = 'dd';
$dd->index = 20;
$ee = new stdClass;
$ee->name = 'ee';
$ee->index = 10;


$arr = [$aa, $bb, $dd, $cc,  $ee];
$map = [30, 30 , 10,  20];

function sort_ish($arr, $map)
{
    $return = [];

    while($element = array_shift($map))
    {
        foreach($arr as $key => $value)
        {
            if($element == $value->index)
            {
                $return[] = $value;
                unset($arr[$key]);
                break 1;
            }
        }
    }

    return $return;
}

print_r(sort_ish($arr, $map));

将输出:

Array
(
    [0] => stdClass Object
(
    [name] => aa
[index] => 30
        )

    [1] => stdClass Object
(
    [name] => bb
[index] => 30
        )

    [2] => stdClass Object
(
    [name] => cc
[index] => 10
        )

    [3] => stdClass Object
(
    [name] => dd
[index] => 20
        )

)

真的,我不得不使用 foreach。

另一方面,我对这个问题很感兴趣,即使我没有做对。谢谢大佬。

【讨论】:

    【解决方案2】:

    我通过在技术上不调用foreach() 循环来完成此操作,但我正在使用递归函数进行循环。您需要做的就是将对象数组 ($arr) 作为第一个参数,将数组映射 ($mapArr) 作为第二个参数传递给函数 mrSorty()。然后mrSorty() 将从这里通过神奇的函数(例如array_search()ksort())传递您的对象数组。

    $arr = [$aa, $bb, $cc, $dd, $ee];
    $mapArr = [30, 20, 10, 10, 30];
    
    function mrSorty($arr, $mapArr, $objCount=0) {
    
        static $newArr; 
    
          if ((count($mapArr)) > 0 && $objCount < ($objCount+count($mapArr)) ) {
    
                $obj = $arr[$objCount];
                $key = array_search($obj->index, $mapArr);
                $newArr[$key] = $obj;
                unset($mapArr[$key]);
                mrSorty($arr, $mapArr, ++$objCount);
          } 
    
          ksort($newArr); //Sort the Array by Key
          return $newArr; 
    }
    
    
    
    $arrayReturn = mrSorty($arr, $mapArr); //Array of Objects & Array Map
    
    var_dump($arrayReturn);
    

    输出

    array(5) {
    [0] => object(stdClass) #1 (2) { ["name"]= > string(2)"aa" ["index"] => int(30)}
    [1] => object(stdClass) #4 (2) { ["name"]= > string(2) "dd" ["index"] => int(20)}
    [2] => object(stdClass) #3 (2) { ["name"]= > string(2) "cc" ["index"] => int(10)}
    [3] => object(stdClass) #5 (2) { ["name"]= > string(2) "ee" ["index"] => int(10)}
    [4] => object(stdClass) #2 (2) { ["name"]= > string(2)"bb" ["index"] => int(30)}
    }
    

    编辑:

    说真的,如果你需要我详细说明,请告诉我。

    【讨论】:

      猜你喜欢
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-06
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      相关资源
      最近更新 更多