【问题标题】:Associative Array - duplicated key values关联数组 - 重复的键值
【发布时间】:2013-12-29 13:59:36
【问题描述】:

我正在做一个简单的购物应用程序,用户可以根据书名、价格、数量等从商店中选择书籍。目前书籍的所有详细信息都保存在一个关联数组中,如下所示:

$menu = array(
array ('id' => '1', 'catagory' => 'newbooks','title' => 'Alex','price' => 4.95, 'desc' => 'bbbb'),

array('id' => '2','catagory' => 'newbooks','title' => 'David ','price' => 5.95, 'desc' => 'sss'),);

}

我想要实现的是合并或删除重复的书籍 ID 条目,而且每本书的标题都将打印在包含“标题”、“ID”、“价格”的单行中

例如:

  1. Alex qty:2 price 4.95
  2. David qty:2 price 5.95 等等……

这是我的购物车文件:

        $buy = array();
        $qty = 0;
        $total = 0;
        foreach ($_SESSION['buy'] as $id) {


            foreach ($menu as $book ) {

                if ($book['id'] == $id) {
                    $buy[] = $book;
                    $total += $book['price'];

                }
            }
        }
    }


    if (count($buy) > 0)
        if (count($book) > 0)
    {
        echo"<table>";
        echo"<tr><th>Item Description</th><th>Quantity</th><th>Price</th></tr>";

        foreach ($buy as $book){


            $f_price = sprintf("%0.2f", $book["price"]);

            echo"<tr><td>" .$book["title"] ."</td>";
            echo"<td>" .$qty."</td><";
            echo"<td>" .$f_price."</td></tr>";
        }

        echo"<tr><td>Total</td><td>".$total."</td></tr>";
        echo"</table>";
    }

我将非常感谢任何帮助或建议,因为我花了很长时间尝试使用独特的函数来解决这个问题,for 语句 foreach 循环但徒劳无功,我仍然是新手,也请尽量宽容一点。干杯!

【问题讨论】:

标签: php arrays associative-array


【解决方案1】:

未经测试,但这应该可以满足您的需求,使用 array_count_values 获取您正在寻找的数量以及一些更改,以使脚本更高效且更易于管理。

<?php
//the ids of the items the user wants to buy
$ids=$_SESSION['buy'];

//Your database of items
$menu = array(
    array ('id' => '1', 'catagory' => 'newbooks','title' => 'Alex','price' => 4.95, 'desc' => 'bbbb'),
    array('id' => '2','catagory' => 'newbooks','title' => 'David ','price' => 5.95, 'desc' => 'sss')
);
//Create a reverse look-up for the database
$lookUp=array();
foreach($menu as $i=>$v)$lookUp[$v['id']]=$menu[$i];



//populate the cart with items, their quantities, and a total
$cart = array();
$total = 0;
foreach (array_count_values($ids) as $id=>$quantity)
{

    if (!array_key_exists($id, $lookUp))continue;
    $item=$lookUp[$id];
    $itemTotal=$item['price']*$quantity;
    $total+=$itemTotal;
    $cart[]=array_merge($item,array('quantity'=>$quantity,'itemTotal'=>$itemTotal));
}


if(count($cart) > 0)
{
    echo '<table>';
    echo '<tr><th>Item Description</th><th>Quantity</th><th>Price</th><th>Item Total</th></tr>';
    foreach ($cart as $item)
    {

    echo sprintf('<tr><td>%s</td><td>%s</td><td>%0.2f</td><td>%0.2f</td></tr>',
        $item["title"],$item['quantity'],$item['price'],$item['itemTotal']);
    }
    echo '<tr><td colspan="3" style="text-align:center;">Total</td><td>'.$total.'</td></tr>';
    echo '</table>';
}

【讨论】:

  • 这简直太棒了!你能解释一下'lookUp'实际上做了什么以及在这种情况下'$v'变量的目的是什么?
  • $lookUp 为您的项目数据库创建反向查找。假设用户的会话包含项目:array(1,2,2,2,1) 对于 id 为“1”的项目,我们想要这样:array ('id' =&gt; '1', 'catagory' =&gt; 'newbooks','title' =&gt; 'Alex','price' =&gt; 4.95, 'desc' =&gt; 'bbbb') 我们如何获取它?它位于$menu[0],但谁说如果您在某个时候删除某个项目就不会丢失 ID?因此,我们希望能够获得 $menu 中项目的索引。所以我们参考 $lookUp['1'] 返回 0。然后我们使用 0 来获取项目信息。 $lookUp
  • foreach($menu as $i=&gt;$v) 这会在 $menu 中循环两次。第一次 $i 将是 0 并且 $v 将是array ('id' =&gt; '1', 'catagory' =&gt; 'newbooks','title' =&gt; 'Alex','price' =&gt; 4.95, 'desc' =&gt; 'bbbb')。第二次 $i 将是 1,$v 将是array('id' =&gt; '2','catagory' =&gt; 'newbooks','title' =&gt; 'David ','price' =&gt; 5.95, 'desc' =&gt; 'sss')。关于赋值:$lookUp[$v['id']]=$menu[$i];第一次赋值$lookUp[1]=0;第二次赋值$lookUp[2]=1;
  • 非常感谢,现在我可以继续我的申请了。
  • 请务必点赞有用的答案并选择最佳答案。
【解决方案2】:

如果它只是基于 id,当你构建数组时,将 book id 作为键存储在更大的数组中,所以你的最终数组是:

$books = array(
   1=> array ('id' => '1', [...]),
   2=> array ('id' => '2', [...])
);

您还可以添加一些代码来检查您何时尝试为该数组分配值以查看键是否已设置。

if(!isset($books[$book_id])){
  //Add to the array
}else{
   //Maybe display an error?
}

PS:类别中只有一个a

【讨论】:

  • 猜否决票是恶意的?这是组织集合的正确方法 - 否则任何强制唯一性的尝试都是详尽无遗的。
  • @Hardy 我认为你不明白我的回答。首先,我没有说任何关于会议的事情。其次,OP问题是关于防止重复。您在此处的回复表明您将有重复。
【解决方案3】:

对收藏中的书籍进行库存概览是一种非常麻烦的方法,但除此之外:)

如果我要使用这样的数组,(我永远不会这样做:))我会首先选择所有唯一的键,然后一个接一个地遍历它们,计算它在$menu 数组。 如下:

$unique_books = array_unique($menu);

foreach($unique_books as $book){

 $qty = array_keys($menu, $book["id"])
 $book["qty"] = $qty;
 $stock = $book;

}

如您所见,现在 $stock 将成为唯一数组,其中添加了一个 qty,其中包含 id 在 $menu 中出现的次数。 这只是一个快速代码块,应该是 testet,但我认为该理论有效。正如我之前提到的,你首先制作这个的方式不是很聪明,你应该重新考虑整个事情 imo :)

【讨论】:

    【解决方案4】:

    如果你不想重复简单的使用 book_id 作为购买数组的键

    例子:

     $menu = array(
        array('id' => '1', 'catagory' => 'newbooks','title' => 'Alex','price' => 4.95, 'desc' => 'bbbb'),
        array('id' => '2','catagory' => 'newbooks','title' => 'David ','price' => 5.95, 'desc' => 'sss')
    );
    $session=array(1,2,2,2,1);
    $buy = array();
    
            foreach ($session as $id) {
                foreach ($menu as $book) {
                    if ($book['id'] == $id) {
                        if(isset($buy[$id])){
                            $buy[$id]['qty']++; // increase quantity
                            $buy[$id]['total'] += $book['price']; // total price only for this id
                            $buy['total'] += $book['price']; // All ids price total
                        }else{
                            $buy[$id] = $book; // assign new id to the buy array
                            $buy[$id]['qty'] = 1; // quantity reset to 1
                            $buy[$id]['total'] = $book['price']; // id price
                            $buy['total'] += $book['price']; // total price
                        }
          }  
       }
    }
    print_r($buy);
    

    你可以在这里测试它!

    http://codepad.org/wH2WskLG

    【讨论】:

    • Perfecto,这正是我一直在努力实现的目标。您能否更具体地说明如何增加每个图书 ID 的数量和价格?
    【解决方案5】:

    您应该将书籍 ID 和数量作为数组行添加到会话中,而不是合并重复项。

    在会话开始时..

    if (!isset($_SESSION['buy']))
      $_SESSION['buy'] = array();
    

    添加新时..

    $new_book = $added_book; // just for example
    $qty = $added_qty; // Added qty
    
    // Check if book already exists in shopping cart and update qty
    if (array_key_exists($new_book['id'], $_SESSION['buy'])) {
       $_SESSION['buy'][$new_book['id']] += $qty;
    } else {
       $_SESSION['buy'][$new_book['id']] = $qty;
    }
    

    然后在购物车视图中循环浏览您的商品..

     foreach($menu as $book ) {
    
    
       if (array_key_exists($book['id'], $_SESSION['buy'])) {
          // User bought this book..
    
          $qty = $_SESSION['buy'][$book['id']];
       }
    
     }
    

    【讨论】:

    • @jessica 您是否期望我编写整个代码来处理购物车?这只是应该如何完成的示例。检查我更新的答案..
    • 您的原始答案不包含与防止重复有关的任何内容。另外,您的新代码充满了问题。当人们批评你时,不要太个人化,请成熟一点。
    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 2015-07-23
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 2017-06-17
    • 2016-05-23
    • 2018-11-11
    相关资源
    最近更新 更多