【问题标题】:Separating a list of entries by the first letter in a given field通过给定字段中的第一个字母分隔条目列表
【发布时间】:2011-06-28 11:41:01
【问题描述】:

我正在尝试按条目标题的第一个字母列出一系列条目。

我将如何做到这一点,并且 b 将每个字母与每个字母分开。

谢谢

假设我有两个头衔:

Much Ado About Nothing
The Tempest

我需要根据第一个字母分隔标题:

//
K
L
M - Much Ado About Nothing
N
//
S
T The Tempest
U
V

等等

编辑:这是我拥有的数组,我需要从中选择标题:

Array
(
[0] => Array
    (
        [id] => 1
        [title] => Test Article
        [author] => Shamil
        [date] => 1309039548
        [summary] => Summary of test article
        [content] => 

Technical article Content.


        [category] => technical
        [published] => 0
    )

)

【问题讨论】:

  • 你能举例说明输入是什么以及输出应该是什么样子吗?
  • 您是否从数据库、文件或任何其他资源中获取标题?
  • 你想把它存储在某个地方吗?或者只是创建一个数组并在应用程序中使用它? “条目列表”是一个数组吗?
  • 我不需要存储它——但它只需要动态生成。标题存储在数据库中。

标签: php


【解决方案1】:

假设所有这些条目都在一个数组中,并且标题大写,您可以执行以下操作:

$entries = array(...); // the original entries
sort($entries);

$alphabetized = array();
foreach (range('A', 'Z') as $letter) {
    $alphabetized[$letter] = array();
}

foreach ($entries as $entry) {
    array_unshift($alphabetized[$entry[0]], $entry);
}

这个算法的唯一问题是它会将“矩阵”之类的东西按字母顺序排列在 T 而不是 M 下。但至少这是一个开始。

更新:
这是我为处理“The”和“A”而编写的代码:

<?php
$entries = array(
    array('title' => 'Much Ado About Nothing'),
    array('title' => 'Star Wars'),
    array('title' => 'The Tempest'),
    array('title' => 'A Wrinkle In Time'),
    array('title' => 'Star Trek'),
    array('title' => 'The'),
    array('title' => 'A')
);

function shamil_title_compare($a, $b) {
    return strcasecmp($a['title'], $b['title']);
}

usort($entries, 'shamil_title_compare');

$alphabetized = array();
foreach (range('A', 'Z') as $letter) {
    $alphabetized[$letter] = array();
}

foreach ($entries as $entry) {
    $title = $entry['title'];
    $firstWord = strtok($title, ' ');
    if (!in_array($firstWord, array('The', 'A'))) {
        $alphabetized[$firstWord[0]][] = $entry;
    } else {
        $nextWord = strtok(' ');
        if ($nextWord !== false) {
            $alphabetized[$nextWord[0]][] = $entry;
        } else {
            $alphabetized[$firstWord[0]][] = $entry;
        }
    }
}

更新 2 我更新了我的代码,将按字母顺序排列的列表输出到 html 无序列表中:

<?php
$entries = array(
    array('title' => 'Much Ado About Nothing'),
    array('title' => 'Star Wars'),
    array('title' => 'A Quantum of Solace'),
    array('title' => 'The Tempest'),
    array('title' => 'Cat Attack'),
    array('title' => 'A Wrinkle In Time'),
    array('title' => 'Star Trek'),
    array('title' => 'The Cat'),
    array('title' => 'Wicked Witch of the West'),
);

// Build a copy of the original, but strip "The" and "A", and lowercase it.
$sort = array();
foreach ($entries as $index => $array)
{
    $title = strtoupper($array['title']);
    list($head, $tail) = explode(' ', $title, 2);

    if (($head !== 'A') and ($head !== 'THE'))
    {
        $sort[] = $title;
    }
    else if ($tail != '')
    {
        $sort[] = $tail;
    }
    else
    {
        $sort[] = $head;
    }
}

array_multisort($sort, SORT_ASC, SORT_STRING, $entries);

$alphabetized = array();
foreach (range('A', 'Z') as $letter)
{
    $alphabetized[$letter] = array();
}

foreach ($sort as $index => $title)
{
    $letter = $title[0];
    $alphabetized[$letter][] = $entries[$index];
}

// Output as html
foreach ($alphabetized as $letter => $entries)
{
    echo "<h3>{$letter}</h3>", PHP_EOL,
        "<ul>", PHP_EOL;
    foreach ($entries as $entry)
    {
        echo "<li>{$entry['title']}</li>", PHP_EOL;
    }
    echo "</ul>", PHP_EOL;
}

【讨论】:

  • 我想你可以对这个算法做的一个改进是检查标题的第一个单词,看看它是像“The”还是“A”,如果是,使用substr获取下一个单词并根据该单词按字母顺序排列。
  • 不喜欢 `array_unshift($alphabetized[$entry[$firstWord[0]]], $entry);` 注意:未定义索引:T.
  • @Shamil 我已经更新为更简单的代码,当我测试它时它不会给出任何错误或通知。试试看,如果您有任何问题,请告诉我。
  • 整合这是我痛苦的事情-.-.
  • @Shamil 我添加了新代码,它将为您输出一个 html 列表。我还改进了字母顺序,我认为我以前的代码可能无法正确按字母顺序排列。
猜你喜欢
  • 2018-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多