The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]



"Красиво собрать массив из глубин JSON"
Вариант для распечатки  
Пред. тема | След. тема 
Форум WEB технологии (Perl)
Изначальное сообщение [ Отслеживать ]

"Красиво собрать массив из глубин JSON"  +/
Сообщение от GoldenCeylon (?), 08-Фев-19, 09:13 
Всем привет!
Ломаю голову..

Есть JSON:
print Dumper($json);
$VAR1 = [
{
  "id" : "1",
  "name" : "Name1"
},
{
  "id" : "2",
  "name" : "Name2"
},
{
  "id" : "3",
  "name" : "Name3"
}
]
Список может быть большой

Их него нужно вытащить все элементы "name" и запихнуть их в одномерный массив: @names = ("Name1", "Name2", "Name3")

Первое что приходит в голову:
for my $elem ( @$json ){
push @names, $elem->{"name"};
}
print Dumper(@names);

Ну, имеем то, что хотели:
#Name1Name2Name3

ВОПРОС
Есть способ получить желаемое в одно касание, без перебора? По типу, как взять 1 элемент:
$name = $json->[0]->{"name"};
так хотелось бы сразу все "name"

Спасибо.

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения [Сортировка по времени | RSS]


1. "Красиво собрать массив из глубин JSON"  +/
Сообщение от Andrey Mitrofanov (?), 08-Фев-19, 09:24 
> ВОПРОС
> Есть способ получить желаемое в одно касание, без перебора? По типу, как
> взять 1 элемент:
> $name = $json->[0]->{"name"};
> так хотелось бы сразу все "name"
> Спасибо.

Э... это _должно_ называться map().  Я почти :) уверен.

Перла не знаю, "но вы держитесь":

$ dat() { echo '[ -- json SKIPPED --]'; }
$ dat |jq '[.[].name]'
[
  "Name1",
  "Name2",
  "Name3"
]
$ dat |jq 'map(.name)'
[
  "Name1",
  "Name2",
  "Name3"
]
$ _

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "Красиво собрать массив из глубин JSON"  +/
Сообщение от михалыч (ok), 08-Фев-19, 16:29 
> Э... это _должно_ называться map().  Я почти :) уверен.

да, есть это

print join("," , map{ $_->{name}} @{$json});

> Перла не знаю, "но вы держитесь":

скромничаешь! хых ))
и всё-то ты знаешь

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

4. "Красиво собрать массив из глубин JSON"  +1 +/
Сообщение от GoldenCeylon (?), 11-Фев-19, 12:23 
> print join("," , map{ $_->{name}} @{$json});

Подитожу:
@names = map{$_->{name}} @{$json};
или
@names = map{$_->{name}} @$json;

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

3. "Красиво собрать массив из глубин JSON"  +/
Сообщение от Аноним (3), 10-Фев-19, 05:06 
> Всем привет!
> Ломаю голову..
> Список большой
> Есть способ получить желаемое?
> И хотелось бы сразу всё!
> Спасибо.

Ok google!
Как сделать мне хорошо и красиво?

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

5. "Красиво собрать массив из глубин JSON"  +/
Сообщение от Аноним (5), 14-Фев-19, 13:53 
Без перебора только так. Регулярку не проверял.

my @names = $json_str =~ m/name["\s]*:\s*"([^"]+)/g ;

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

7. "Красиво собрать массив из глубин JSON"  +/
Сообщение от михалыч (ok), 06-Мрт-19, 10:20 
> Без перебора только так. Регулярку не проверял.
> my @names = $json_str =~ m/name["\s]*:\s*"([^"]+)/g ;

не взлетит

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

10. "re: не взлетит"  +/
Сообщение от Шёл мимо (?), 10-Авг-19, 09:18 
> не взлетит


#!/usr/bin/perl

use strict;
use warnings;
use JSON;
use Data::Dumper;
use Benchmark 'cmpthese';

my $json_text = '[
{
  "id" : "1",
  "name" : "Name1"
},
{
  "id" : "2",
  "name" : "Name2"
},
{
  "id" : "3",
  "name" : "Name3"
}]'
;

#my $json = JSON->new->decode($json_text);
my $json = decode_json($json_text);

print Dumper($json);

sub mapng {
    my @names = map { $_->{name} } @{$json};

}

sub modif {
    push my @names, $_->{name} for @{$json};
}

sub cycle {
    for ( @{$json} ) {
        push my @names, $_->{name};
    }
}
sub ptext {
    my @names = ($_[0] =~ /^\s*+"name" *+: *+"([^"]*+)"/mg);
#    print Dumper(@names);
}
#ptext($json_text);

cmpthese(
  -1,
  {
    'mapng' => sub { mapng($json) },
    'modif' => sub { modif($json) },
    'cycle' => sub { cycle($json) },
    'ptext' => sub { ptext($json_text) },
  }
);
__END__


ptext  92781/s    --  -63%  -67%  -67%
mapng 251601/s  171%    --  -11%  -12%
cycle 281553/s  203%   12%    --   -1%
modif 284630/s  207%   13%    1%    --

Если правильно понял

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

6. "Красиво собрать массив из глубин JSON"  +/
Сообщение от erera22 (ok), 18-Фев-19, 20:44 
еще до кучи:
push @names, $_->{name} for @$json;
Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

8. "Красиво собрать массив из глубин JSON"  +/
Сообщение от михалыч (ok), 06-Мрт-19, 10:31 
> еще до кучи:
> push @names, $_->{name} for @$json;

в данном случае for используется как модификатор, но суть дела от этого не меняется
и это фактически, да и практически ничем не отличается от классического перебора в цикле

for ( @{$json} ) {
    push @names, $_->{name};
}

написано короче,
но ещё не известно, что быстрей и лучше для понимания и восприятия
(в данном конкретном случае) ))

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

9. "Красиво собрать массив из глубин JSON"  +1 +/
Сообщение от михалыч (ok), 09-Мрт-19, 18:31 
дело было вечером, делать было нечего,
было скучно..

вспомнил бородатый анекдот дневник джигита (абрека),

захотел вернуться к этому и выяснить, что быстрее работает,
потому как map тоже является циклом, только хитрозаточенным,
в отличии от for (foreach) и, думаю, не очень его быстрее

и чтобы хейтеры (не путать с хипстерами) не начали своё любимое
"пруф или трепло", решил - хайпанём, немножечко? ))

вот proof, сиречь доказательство


#!/usr/bin/perl

use strict;
use warnings;
use JSON;
use Data::Dumper;
use Benchmark 'cmpthese';


my $json_text = '[
{
  "id" : "1",
  "name" : "Name1"
},
{
  "id" : "2",
  "name" : "Name2"
},
{
  "id" : "3",
  "name" : "Name3"
}]'
;

#my $json = JSON->new->decode($json_text);
my $json = decode_json($json_text);

print Dumper($json);

sub mapng {
    my @names = map { $_->{name} } @{$json};

}

sub modif {
    push my @names, $_->{name} for @{$json};
}

sub cycle {
    for ( @{$json} ) {
        push my @names, $_->{name};
    }
}


cmpthese(
  -1,
  {
    'mapng' => sub { mapng($json) },
    'modif' => sub { modif($json) },
    'cycle' => sub { cycle($json) },
  }
);

__END__


что видим?
что так и да, mapping быстрее, но не в разы

# ./test.pl
$VAR1 = [
          {
            'name' => 'Name1',
            'id' => '1'
          },
          {
            'name' => 'Name2',
            'id' => '2'
          },
          {
            'name' => 'Name3',
            'id' => '3'
          }
        ];
          Rate mapng cycle modif
mapng 239064/s    --   -8%   -9%
cycle 260979/s    9%    --   -1%
modif 262926/s   10%    1%    --

выигрыш по скорости небольшой, всего лишь код немного короче (красивее? ;) ),
(думаю, что map выгоден для обработки и трансформации массива в другой массив)

такие дела

блин, опять скучно..

Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

11. "Красиво собрать массив из глубин JSON"  +/
Сообщение от Шёл мимо (?), 10-Авг-19, 09:34 
Наверное ответ был на этот пост
Ответить | Правка | ^ к родителю #9 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Спонсоры:
Слёрм
Inferno Solutions
Hosting by Ihor
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2019 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру