首頁 > 後端開發 > php教程 > PHP中的傳感器變得容易

PHP中的傳感器變得容易

Christopher Nolan
發布: 2025-02-15 11:36:11
原創
919 人瀏覽過

深入PHP函數式編程:探秘Transducers

你可能聽說過函數式編程和高階函數,但你了解Transducers嗎?本文將帶你探索這個強大的數據轉換工具。

Transducers in PHP Made Easy

核心要點:

  • Transducers源於Clojure,由Michael Dowling移植到PHP,是一種構建可重用算法轉換的強大方法。它們是接受一個約簡函數並返回另一個約簡函數的函數。
  • PHP的Transducers包允許以多種方式轉換數據,例如將名稱的首字母大寫或從用戶列表中刪除未成年人。轉換可以組合成單個Transducer以供重用。
  • Transducer中的約簡函數接收一個值作為參數,並返回一個包含三個元素的約簡函數數組:“init”(初始值)、“result”(最終結果)和“step”(約簡邏輯)。
  • Transducers的優勢在於它將數據轉換過程與實際數據源分離,使代碼更模塊化、更易於維護。它們允許創建可重用的軟件組件,可用於任何數據源。然而,由於其函數式編程的根源,它們可能比傳統的PHP函數更複雜。

Transducers定義

要理解Transducers,首先需要了解約簡器(Reducers)。引用Rich Hickey的話:

一個約簡函數正是你傳遞給reduce的函數類型——它接收迄今為止的結果和一個新的輸入,並返回下一個迄今為止的結果。

一個Transducer是一個函數,它接收一個約簡函數並返回另一個約簡函數。

Transducers最初由Rich Hickey引入Clojure,並由Michael Dowling移植到PHP。 Transducers是構建可在多種情況下重用的算法轉換的強大方法。本文將通過一系列實際示例來探討其用途。

示例

在繼續之前,我們需要通過Composer安裝Transducers包。

composer require mtdowling/transducers
登入後複製
登入後複製
登入後複製

我們將為以下示例使用一個簡單的User類。

class User
{
    public $id;
    public $name;
    public $age;

    public function __construct($id, $name, $age)
    {
        $this->id = $id;
        $this->name = $name;
        $this->age = $age;
    }

    public function __toString()
    {
        return sprintf("\n%d - %s - %d", $this->id, $this->name, $this->age);
    }
}

// 示例数据
$data = [
    new User(1, "younes", 24),
    new User(2, "youssef", 26),
    new User(3, "hamza", 25),
    new User(4, "ismail", 17),
];
登入後複製
登入後複製
use Transducers as t;

$uppercase = t\map(function($user) { 
    return new User($user->id, ucfirst($user->name), $user->age); 
});

$result = t\xform($data, $uppercase);

var_dump($result);
登入後複製
登入後複製

map函數類似於PHP的array_map函數:我們傳遞一個可調用函數,在本例中,它將把用戶名首字母大寫。

我們使用xform函數應用我們的uppercase Transducer。它將我們的數據作為第一個參數,Transducer作為第二個參數。

// 输出
array(4) {
  [0]=>
  object(User)#14 (3) {
    ["id"]=>
    int(1)
    ["name"]=>
    string(6) "Younes"
    ["age"]=>
    int(24)
  }
  [1]=>
  object(User)#15 (3) {
    ["id"]=>
    int(2)
    ["name"]=>
    string(7) "Youssef"
    ["age"]=>
    int(26)
  }
  [2]=>
  object(User)#16 (3) {
    ["id"]=>
    int(3)
    ["name"]=>
    string(5) "Hamza"
    ["age"]=>
    int(25)
  }
  [3]=>
  object(User)#17 (3) {
    ["id"]=>
    int(4)
    ["name"]=>
    string(6) "Ismail"
    ["age"]=>
    int(17)
  }
}
登入後複製
登入後複製

xform返回與數據參數相同類型的值(在本例中為數組)。如果嚴格需要輸出數組,我們也可以使用to_array

// ...
$result = t\to_array($data, $uppercase);
// ...
登入後複製
登入後複製

我們也可以使用to_string將輸出轉換為字符串,或者使用into($target, $coll, callable $xf)將輸出轉換為特定類型。更多細節請查看文檔。

composer require mtdowling/transducers
登入後複製
登入後複製
登入後複製
class User
{
    public $id;
    public $name;
    public $age;

    public function __construct($id, $name, $age)
    {
        $this->id = $id;
        $this->name = $name;
        $this->age = $age;
    }

    public function __toString()
    {
        return sprintf("\n%d - %s - %d", $this->id, $this->name, $this->age);
    }
}

// 示例数据
$data = [
    new User(1, "younes", 24),
    new User(2, "youssef", 26),
    new User(3, "hamza", 25),
    new User(4, "ismail", 17),
];
登入後複製
登入後複製

Transducers最棒的部分是我們可以將多個轉換組合成一個Transducer。例如,讓我們將用戶名的首字母大寫並刪除未成年人。

use Transducers as t;

$uppercase = t\map(function($user) { 
    return new User($user->id, ucfirst($user->name), $user->age); 
});

$result = t\xform($data, $uppercase);

var_dump($result);
登入後複製
登入後複製

filter函數類似於PHP的array_filter函數。 comp函數從Transducer列表創建一個Transducer,在本例中為uppercase(使用map)和removeMinors(使用filter)。

// 输出
array(4) {
  [0]=>
  object(User)#14 (3) {
    ["id"]=>
    int(1)
    ["name"]=>
    string(6) "Younes"
    ["age"]=>
    int(24)
  }
  [1]=>
  object(User)#15 (3) {
    ["id"]=>
    int(2)
    ["name"]=>
    string(7) "Youssef"
    ["age"]=>
    int(26)
  }
  [2]=>
  object(User)#16 (3) {
    ["id"]=>
    int(3)
    ["name"]=>
    string(5) "Hamza"
    ["age"]=>
    int(25)
  }
  [3]=>
  object(User)#17 (3) {
    ["id"]=>
    int(4)
    ["name"]=>
    string(6) "Ismail"
    ["age"]=>
    int(17)
  }
}
登入後複製
登入後複製

現在我們有一個可重用的Transducer組合,我們可以隨時使用它來根據此標準約簡數據。查看文檔以了解可用約簡函數的列表。

創建Transducer

約簡函數接收一個值作為參數,並返回一個約簡函數數組,該數組必須包含三個元素:

  • init:返回Transducer初始值的函數。如果未提供初始值,則僅在第一次調用時調用。
  • resultresult函數用於根據調用棧構建最終結果。
  • step:這是你編寫約簡邏輯的地方——根據你的約簡邏輯,你可能調用它零次或多次。

如果沒有實際代碼,這會變得非常混亂,因此讓我們以take Transducer函數為例。它從數據數組頂部獲取n個項目。

// ...
$result = t\to_array($data, $uppercase);
// ...
登入後複製
登入後複製
use Transducers as t;

$uppercase = t\map(function($user) { 
    return new User($user->id, ucfirst($user->name), $user->age); 
});

$result = t\to_string($data, $uppercase);

var_dump($result);
登入後複製

以下是take約簡函數的源代碼。

// 输出
string(64) "
1 - Younes - 24
2 - Youssef - 26
3 - Hamza - 25
4 - Ismail - 17"
登入後複製

take函數被多次調用,帶有resultinput參數。每次調用時,它都會遞減remaining變量並測試它是否小於零。在這種情況下,我們返回一個Reduced對象實例,這表示一個停止點。

我們的Transducer函數示例將從數據中刪除空元素。使用前面關於Transducer工作原理的解釋,我們可以訪問$input變量,並決定是調用下一個step回調還是簡單地返回值。

$uppercase = t\map(function($user) { 
    return new User($user->id, ucfirst($user->name), $user->age); 
});
$removeMinors = t\filter(function($user) { 
    return $user->age >= 18;
});

$comp = t\comp(
    $uppercase,
    $removeMinors
);

$result = t\to_string($data, $comp);

var_dump($result);
登入後複製

我們可以通過向我們的$data變量添加一些空項目來測試這一點。

// 输出
string(48) "
1 - Younes - 24
2 - Youssef - 26
3 - Hamza - 25"
登入後複製
// ....
$comp = t\comp(
    $uppercase,
    $removeMinors,
    t\take(2)
);

$result = t\to_string($data, $comp);

var_dump($result);
登入後複製

結論

在本文中,我們了解了函數式編程世界的一個新方面,稱為Transducers。我們回顧了Transducers的目的,即使數據轉換更容易。我們還回顧了一些示例,以更好地演示Transducers的價值。你現在在你的開發者工具箱中擁有了一個新的工具,或者至少對Transducer的概念有了更好的理解。

如果你對Transducers有任何疑問,可以在下面發表!

PHP中Transducers的常見問題

PHP中Transducers的基本概念是什麼?

PHP中的Transducers是一種數據處理技術,允許你創建可組合和可重用的軟件組件。它們本質上是接受一個約簡器並返回一個新約簡器的函數。這個概念借鑒自Clojure和JavaScript,並已適應PHP。 Transducers允許你將數據轉換過程與實際數據源分離,使你的代碼更模塊化、更易於維護。

Transducers與傳統的PHP函數有何不同?

傳統的PHP函數通常將獲取數據和轉換數據的過程結合在一起,這可能導致難以維護和重用的代碼。另一方面,Transducers將這兩個過程分開。這意味著你可以創建一個以特定方式轉換數據的Transducer,然後將其與任何數據源一起使用,使你的代碼更靈活、更可重用。

你能提供一個PHP中Transducer的示例嗎?

當然,讓我們考慮一個簡單的示例。假設你有一個數字數組,並且你想將每個數字加1。你可以創建一個執行此操作的Transducer:

composer require mtdowling/transducers
登入後複製
登入後複製
登入後複製

然後,你可以將此Transducer與任何約簡函數和數據源一起使用。

如何將Transducers與不同的數據源一起使用?

Transducers設計用於與任何數據源一起使用。這是因為它們在單個數據項級別運行,而不是在整個數據源級別運行。因此,你可以將Transducer與數組、數據庫查詢結果、來自網絡連接的數據流等一起使用。唯一的要求是你的數據源必須能夠與約簡函數一起工作。

使用PHP中的Transducers有哪些好處?

Transducers提供了許多好處。它們允許你將數據轉換過程與實際數據源分離,使你的代碼更模塊化、更易於維護。它們還允許你創建可重用的軟件組件,可用於任何數據源。最後,因為Transducers操作單個數據項,所以在處理大型數據集時,它們可能比傳統的PHP函數更高效。

使用PHP中的Transducers有哪些缺點?

雖然Transducers提供了許多好處,但它們也可能比傳統的PHP函數更複雜。這是因為它們涉及函數式編程的概念,這些概念對一些PHP開發人員來說可能不熟悉。但是,一旦你理解了Transducers的工作原理,它們就可以成為編寫乾淨、高效和可重用代碼的強大工具。

Transducers可以與PHP框架一起使用嗎?

是的,Transducers可以與任何PHP框架一起使用。它們是一種通用的數據處理技術,不依賴於任何特定的框架特性。但是,一些框架可能提供自己用於處理Transducers的實用程序,這可以使它們更容易使用。

如何學習更多關於PHP中Transducers的知識?

有很多資源可用於學習PHP中的Transducers。你可以從閱讀網上的文章和教程開始,例如SitePoint上的文章。還有一些書籍和在線課程更深入地介紹了這個主題。最後,你可以嘗試編寫自己的Transducers並在你的PHP項目中使用它們。

Transducers在其他編程語言中使用嗎?

是的,Transducers的概念起源於Clojure編程語言,此後已被其他幾種語言採用,包括JavaScript和PHP。每種語言都以自己的方式實現Transducers,但基本概念是相同的。

我可以將Transducers與PHP內置的數組函數一起使用嗎?

是的,你可以將Transducers與PHP內置的數組函數一起使用。但是,請記住,這些函數可能不如使用Transducer高效,尤其是在處理大型數組時。這是因為PHP的數組函數通常會創建新的數組,而Transducer可以在原地轉換數據。

以上是PHP中的傳感器變得容易的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板