Advertisement
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Change key of certain elements in Array

Comments in 'Plugin Development' started by Primus, Aug 19, 2016.

  1. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    What is the most efficient way to do it? I need to do order the array and make three of keys in front of others (ascending order)
    Code:
    0 => BoomX
    1 => Safezone
    2 => Ninjaz
    3 => Warzone
    4 => Wilderness
    
    But it must be
    Code:
    0 => Wilderness
    1 => Warzone
    2 => Safezone
    3 => BoomX
    4 => Ninjaz
    
    My current code. It doesn't order the factions right now.
    PHP:
    public function loadSavedFactions()
      {
      foreach (
    scandir(self::$factionFolder) as $file) {
      if (
    $file == "." or $file == "..") continue;
      
    $name $file;
      
    $data $this->getSavedFactionData($name);
      if (empty(
    $data)) {
      
    $this->getPlugin()->getLogger()->warning("Failed to load faction: " $name);
      continue;
      }
       
    // Directly attach it to storage if any error happens while creating a object, it will self-detach
      
    Factions::attach(new Faction($data["name"], $data["id"], $data));

      if (
    Factions::getById($data["id"])) {
      
    $this->getPlugin()->getLogger()->info("Faction " $data["name"] . " loaded!");
      continue;
      } else {
      
    $this->getPlugin()->getLogger()->info("Unknown error occured while loading faction: " $data["name"]);
      continue;
      }
      }
    Possible solution:
    PHP:
    $factions = ["wilderness""warzone""safezone"];
    foreach(...) {
       if(
    $file == '.' or $file == '..' or in_array($file$factionstrue)) continue;
    }
    Actually I don't expect to get solution. I'm trying to make this community live again by asking as many questions as possible from now on :D
    Last edited: Aug 19, 2016
    PocketKiller likes this.
  2. PocketKiller
    Offline

    PocketKiller Notable Member

    Joined:
    Jul 20, 2015
    Posts:
    741
    This might help.
    http://php.net/manual/en/array.sorting.php
    http://php.net/manual/en/function.sort.php
    Primus likes this.
  3. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    PHP:
    function sortWithPriority(array &$array){
      
    usort($array, function($a$b){
        if(
    $a === "Wilderness") return -1// Wilderness should always come first
        
    if($b === "Wilderness") return 1// Wilderness should always come first
        
    if($a === "Warzone") return -1// $b was confirmed on line 4 not Wilderness, so Warzone is the next to come first
        
    if($b === "Warzone") return 1// $a was confirmed on line 3 not Wilderness, so Warzone is the next to come first
        
    return $a <=> $b// normal alphabetical sorting
      
    });
    }
    If your case has an unknown or large number of exceptional cases, use this method instead:
    PHP:
    function internalPriority(string $name){
      switch(
    $name){
        case 
    "Wilderness":
          return 
    1;
        case 
    "Warzone":
          return 
    2;
        case 
    "Treezone":
          return 
    3;
        case 
    "Spawn":
          return 
    4;
        default:
          return 
    PHP_INT_MAX;
      }
    }
    // OR, if the order comes from a config:
    function internalPriority(string $name, array $configArray){
      
    // example of config array:
      // ["Wilderness", "Warzone", "Treezone", "Spawn"]
      
    if(($pos array_search($name$configArray)) !== false){
        return 
    $pos;
      }
      return 
    PHP_EOL;
    }

    function 
    sortWithPriority(array &$array){
      
    usort($array, function($a$b){
        
    $pa internalPriority($a);
        
    $pb internalPriority($b);
        if(
    $pa !== $pb) return $pa <=> $pb;
        return 
    $a <=> $b;
      });
    }
    Last edited: Aug 19, 2016
    Primus likes this.
  4. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    This is what I planned to use but I really didn't got how to do comparison correctly, thanks bud also the Closures are awesome :D
  5. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    @Primus I edited this post. Included information about how to do it dynamically rather than hardcoding.
  6. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    There is also a third method. You can prepend the "\0" and "\1" bytes before "Wilderness" and "Warzone", so automatically sorting will always put them at the beginning.
    However, this is really bad for many situations, and is not really safe against things such as filename checking, user input sanitation, etc. If I were you, I would adopt the second method.
  7. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    It looks like operator "<=>" is unsupported in previous versions of PHP, is it something new from PHP7?

    Alright, I tested the code and as far as I can tell there's a bug
    Code:
    # Original array
    Array
    (
      [0] => Kelox
      [1] => Mushrooms
      [2] => ICandy
      [3] => Dirtz
      [4] => Warzone
      [5] => FireFly
      [6] => Safezone
      [7] => Nyx
      [8] => Nexus
      [9] => Freon
      [10] => Wilderness
      [11] => jYgx
      [12] => incrementZ
    )
    # Result:
    (
      [0] => Dirtz
      [1] => FireFly
      [2] => Freon
      [3] => ICandy
      [4] => Kelox
      [5] => Mushrooms
      [6] => Nexus
      [7] => Nyx
      [8] => incrementZ
      [9] => jYgx
      [10] => Wilderness
      [11] => Warzone
      [12] => Safezone
    )
    
    PHP:
    function internalPriority(string $name){
      switch(
    $name){
      case 
    "Wilderness":
      return 
    1;
      case 
    "Warzone":
      return 
    2;
      case 
    "Safezone":
      return 
    3;
      case 
    "Spawn":
      return 
    4;
      default:
      return 
    PHP_EOL;
      }
    }

    function 
    sortWithPriority(array &$array){
      
    usort($array, function($a$b){
      
    $pa internalPriority($a);
      
    $pb internalPriority($b);
      if(
    $pa !== $pb) return $pa <=> $pb;
      return 
    $a <=> $b;
      });
    }
       
    $array = ["Kelox""Mushrooms""ICandy""Dirtz""Warzone""FireFly""Safezone""Nyx""Nexus""Freon""Wilderness""jYgx""incrementZ"];
    print_r($array);
    sortWithPriority($array);
    print 
    "\n";
    print_r($array);
  8. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    Oh oops, I meant to return PHP_INT_MAX rather than PHP_EOL :D

    Also, if you want case-insensitive string comparison, try strcasecmp() or strtolower() <=> strtolower()

    Yes, <=> the spaceship operator is something new in PHP 7. See http://stackoverflow.com/documentat...16/spaceship-operator#t=201608191444293904398 for examples.
  9. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    Works :D
    Thanks again

Share This Page

Advertisement