1
\$\begingroup\$

I have an array of available languages for my website, with a short ISO country code as the key for each language. I need to create a new array that contains the same info, but with numerical keys and where the first item in the new array is the current language.

I have this, which works fine:

$allLanguages = [
    'en' => ['locale' => 'en_US', 'code' => 'en', 'displayName' => 'English'],
    'sv' => ['locale' => 'sv_SE', 'code' => 'sv', 'displayName' => 'Swedish'],
    'de' => ['locale' => 'de_DE', 'code' => 'de', 'displayName' => 'German']
];

$currentLanguage = 'sv';


// Create new numerical-ordered array with current language info as first element
$langugeList = [];
foreach( $allLanguages as $key => $value ){
    if( $key == $currentLanguage ) 
        array_unshift($langugeList, $value);
    else 
        array_push($langugeList, $value);
};

Result:

    array (
        0 =>
            array (
                'locale' => 'sv_SE',
                'code' => 'sv',
                'displayName' => 'Swedish',
            ),
        1 =>
            array (
                'locale' => 'en_US',
                'code' => 'en',
                'displayName' => 'English',
            ),
        2 =>
            array (
                'locale' => 'de_DE',
                'code' => 'de',
                'displayName' => 'German',
            ),
    )

Is there another, more elegant way of doing this?

I first had the idea to copy the array values and then sort them using usort() (keeping the original order except for the current language), but that doesn't seem like an improvement to neither performance nor "elegancy".

I just realized that one option would be

$langugeList = [ $allLanguages[$currentLanguage] ];
foreach( $allLanguages as $key => $value ){
    if( $key != $currentLanguage )
        $langugeList[] = $value;
};
\$\endgroup\$
1
  • \$\begingroup\$ I think you have answered your own question. The last example you show, is simple and easy to understand, I would stick with that. \$\endgroup\$
    – bumperbox
    Commented Feb 9, 2018 at 19:02

1 Answer 1

1
\$\begingroup\$

PHP has a function built in for this: array_values()

<?php

$allLanguages = [
    'en' => ['locale' => 'en_US', 'code' => 'en', 'displayName' => 'English'],
    'sv' => ['locale' => 'sv_SE', 'code' => 'sv', 'displayName' => 'Swedish'],
    'de' => ['locale' => 'de_DE', 'code' => 'de', 'displayName' => 'German']
];

var_dump(array_values($allLanguages));

Outputs:

array(3) {
  [0]=>
  array(3) {
    ["locale"]=>
    string(5) "en_US"
    ["code"]=>
    string(2) "en"
    ["displayName"]=>
    string(7) "English"
  }
  [1]=>
  array(3) {
    ["locale"]=>
    string(5) "sv_SE"
    ["code"]=>
    string(2) "sv"
    ["displayName"]=>
    string(7) "Swedish"
  }
  [2]=>
  array(3) {
    ["locale"]=>
    string(5) "de_DE"
    ["code"]=>
    string(2) "de"
    ["displayName"]=>
    string(6) "German"
  }
}

Live Example


If you combine that function with this answer, you can move the desired array element to the top of the array before removing the keys:

<?php

$allLanguages = [
    'en' => ['locale' => 'en_US', 'code' => 'en', 'displayName' => 'English'],
    'sv' => ['locale' => 'sv_SE', 'code' => 'sv', 'displayName' => 'Swedish'],
    'de' => ['locale' => 'de_DE', 'code' => 'de', 'displayName' => 'German']
];

$currentLanguage = 'sv';

// Move the desired language to the front of the array
$allLanguages = [$currentLanguage => $allLanguages[$currentLanguage]] + $allLanguages;

// Get a new array with just the values
$allLanguages = array_values($allLanguages);

var_dump($allLanguages);

Live Example


As a one liner:

<?php

$allLanguages = array_values([$currentLanguage => $allLanguages[$currentLanguage]] + $allLanguages);

Live Example


As a helper function:

<?php

function processLanguages($current, $languages) {
    return array_values([$current => $languages[$current]] + $languages);
}

$allLanguages = [
    'en' => ['locale' => 'en_US', 'code' => 'en', 'displayName' => 'English'],
    'sv' => ['locale' => 'sv_SE', 'code' => 'sv', 'displayName' => 'Swedish'],
    'de' => ['locale' => 'de_DE', 'code' => 'de', 'displayName' => 'German']
];

var_dump(processLanguages('sv', $allLanguages));

Live Example

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.