जब मेरे पास इस बारे में सोचने के लिए एक क्षण था, तो मैं पर्ल के लिए घर वापस भागा और यह काम किया:
use Modern::Perl;
use Moose::Autobox;
use JSON;
my $encoder = JSON->new->pretty;
my $input = [ { 4 => 10 }, { 7 => 9 }, { 90 => 7 }, { 1 => 8 } ];
my $stack = [];
foreach my $item ( reverse @{$input} ) {
while ( my ( $key, $value ) = each %{$item} ) {
my $rec = {
'$cond' => [
{ '$eq' => [ '$user_id', int($key) ] },
$value
]
};
if ( $stack->length == 0 ) {
$rec->{'$cond'}->push( 0 );
} else {
my $last = $stack->pop;
$rec->{'$cond'}->push( $last );
}
$stack->push( $rec );
}
}
say $encoder->encode( $stack->[0] );
तो यह प्रक्रिया बहुत ही सरल थी।
-
सरणी में प्रत्येक आइटम के माध्यम से जाएं और प्रविष्टि के लिए कुंजी और मान प्राप्त करें
-
एक नया "दस्तावेज़" बनाएं जिसमें "$cond" कुंजी के लिए सरणी तर्क में आवश्यक तीन प्रविष्टियों में से केवल दो हों। ये "$user_id" और लौटाए गए "वजन" मान का परीक्षण करने के लिए असाइन किए गए मान हैं।
-
स्टैक . के लिए बाहरी चर की लंबाई का परीक्षण करें , और अगर यह खाली था (पहली बार के माध्यम से) तो पुश
0
. का मान जैसा कि दस्तावेज़ में "$cond" कुंजी के अंत में पिछले नेस्टेड तत्व में देखा गया है। -
अगर वहाँ पहले से कुछ था (लंबाई> 0) तो वह मान लें और पुश यह दस्तावेज़ के लिए "$cond" कुंजी में तीसरे मान के रूप में है।
-
उस दस्तावेज़ को स्टैक . के मान के रूप में वापस रखें और अगले आइटम के लिए दोहराएं
तो लिस्टिंग में कुछ चीजें हैं जैसे इनपुट के क्रम को उलटना, जो आवश्यक नहीं है लेकिन नेस्टेड आउटपुट में प्राकृतिक क्रम उत्पन्न करता है। साथ ही, उस बाहरी "स्टैक" के लिए मेरी पसंद एक सरणी थी क्योंकि परीक्षण ऑपरेटर सरल लग रहे थे। लेकिन यह वास्तव में केवल एक विलक्षण मूल्य है जो फिर से उपयोग, संवर्धित और प्रतिस्थापित होता रहता है।
इसके अलावा JSON प्रिंटिंग सिर्फ आउटपुट दिखाने के लिए है। स्टैक . का परिणामी मूल्य वास्तव में वांछित है संरचना में विलय करने के लिए।
फिर मैंने तर्क को रूबी में बदल दिया, जैसा कि ओपी द्वारा इस्तेमाल की जाने वाली भाषा थी, जहां से मुझे इस नेस्टेड संरचना को उत्पन्न करने की प्रेरणा मिली:
require 'json'
input = [ { 4 => 10 }, { 7 => 9 }, { 90 => 7 }, { 1 => 8 } ]
stack = []
input.reverse_each {|item|
item.each {|key,value|
rec = {
'$cond' => [
{ '$eq' => [ '$user_id', key ] },
value
]
}
if ( stack.length == 0 )
rec['$cond'].push( 0 )
else
last = stack.pop
rec['$cond'].push( last )
end
stack.push( rec )
}
}
puts JSON.pretty_generate(stack[0])
और फिर अंततः उस पाइपलाइन को उत्पन्न करने के लिए अंतिम रूप में जो ओपी चाहता था:
require 'json'
userWeights = [ { 4 => 10 }, { 7 => 9 }, { 90 => 7}, { 1 => 8 } ]
stack = []
userWeights.reverse_each {|item|
item.each {|key,value|
rec = {
'$cond' => [
{ '$eq' => [ '$user_id', key ] },
value
]
}
if ( stack.length == 0 )
rec['$cond'].push( 0 )
else
last = stack.pop
rec['$cond'].push( last )
end
stack.push( rec )
}
}
pipeline = [
{ '$project' => {
'user_id' => 1,
'content' => 1,
'date' => 1,
'weight' => stack[0]
}},
{ '$sort' => { 'weight' => -1, 'date' => -1 } }
]
puts JSON.pretty_generate( pipeline )
तो यह एक user_id
के लिए विशिष्ट "वजन" लागू करने के लिए समग्र रूप से पारित होने वाली संरचना उत्पन्न करने का एक तरीका था और परिणामों को संग्रह में क्रमबद्ध करें।