Выборка из многомерного массива PHP

225
13 ноября 2017, 21:50

Имеется массив:

[{"type":"deposit","currency":"ltc","amount":"0.0","available":"0.0"},
{"type":"deposit","currency":"usd","amount":"631.04896274","available":"0.000001"},
{"type":"exchange","currency":"btc","amount":"0.0","available":"0.0"},
{"type":"exchange","currency":"ltc","amount":"0.00002317","available":"0.00002317"},
{"type":"exchange","currency":"usd","amount":"0.0","available":"0.0"},
{"type":"trading","currency":"ltc","amount":"0.0","available":"0.0"},
{"type":"trading","currency":"usd","amount":"0.0","available":"0.0"}]

Не разобрался, как делать выборку сразу по нескольким ключам. Тупой перебор не хотелось бы =)

Требуется выбрать значение amount, где "type":"deposit","currency":"usd". Переменная $result содержит массив выше.

for ($i = 0; $i <= (count($result)); $i++){
    foreach ($result[$i] as $key => $value) { //интерпретатор уже выплёвывает ошибку "Invalid argument supplied for foreach()"
        if ($key == "usd"){    // а здесь так и подмывает воткнуть ($key == "deposit")&&($key == "usd")
            echo ($key.": ".$value."<br>");
        }
    }
}

Обращаю внимание, что значения ключей в подмассивах могут повторяться.

Заранее спасибо!

Answer 1

Используя JSON

$t='[{"type":"deposit","currency":"ltc","amount":"0.0","available":"0.0"},
{"type":"deposit","currency":"usd","amount":"631.04896274","available":"0.000001"},
{"type":"exchange","currency":"btc","amount":"0.0","available":"0.0"},
{"type":"exchange","currency":"ltc","amount":"0.00002317","available":"0.00002317"},
{"type":"exchange","currency":"usd","amount":"0.0","available":"0.0"},
{"type":"trading","currency":"ltc","amount":"0.0","available":"0.0"},
{"type":"trading","currency":"usd","amount":"0.0","available":"0.0"}]';
$d=json_decode($t,true);

foreach ($d as $v){
    if ($v["type"]=="deposit" && $v["currency"]=="usd") echo $v["amount"]; echo "\n";
}

Проверка http://sandbox.onlinephpfunctions.com/code/a12b16aa231d34782e30522255cb67f9c7ae5bd7

Answer 2

Без перебора не обойтись, но можно уменьшить количество кода с помощью array_filter:

$filtered = array_filter($data, function($item){ 
  return $item['type'] === 'deposit' && $item['currency'] === 'usd';
});
var_dump(reset($filtered));

В Вашем же коде, нужно просто убрать лишний цикл и заменить <= на <:

for ($i = 0; $i < (count($result)); $i++) {
  $item = $result[$i];
  if ($item['type'] === 'deposit' && $item['currency'] === 'usd') {
    var_dump($item);
  }
}

Или проще с foreach:

foreach ($result as $item) {
  if ($item['type'] === 'deposit' && $item['currency'] === 'usd') {
    var_dump($item);
  }
}

Если Вам нужно многократно обращаться к этим данным, стоит предварительно перестроить структуру:

$data = [];
foreach ($result as $item) {
    $data[$item['type']][$item['currency']] = $item;
}
echo "Amount of usd deposit: {$data['deposit']['usd']['amount']}\n";
READ ALSO
Удаление элемента из дерева

Удаление элемента из дерева

Не получается удалить слово из нагруженного дереваСмотрю в дебаге, на последнем узле слова адреса в каждой ячейке массива не NULL и bool не равен...

323
Две параллельные таблички в С++ [требует правки]

Две параллельные таблички в С++ [требует правки]

Суть проблемы такова, требуется нарисовать правила игры (в консоле) в левой стороне, а справа нарисовать поле игры

230
Имеет ли смысл выделять память под объект Mat в куче?

Имеет ли смысл выделять память под объект Mat в куче?

Добрый деньТолько начинаю работать с библиотекой opencv, в связи с чем возник вопрос: Лучше объявлять указатели Mat или же сами объекты?т

205
Как отправить / получить структуру в boost :: asio

Как отправить / получить структуру в boost :: asio

Я собирался отправить структуру с клиента на сервер, используя boost :: asio :: async_write_some, в этом случае boost :: serialization приходит на помощь:

288