我有一个3d矩阵,我需要检查几个元素是否等于一个值(未来每个元素的目标值可能不同)。
有没有办法在最后简化if条件?我希望有一些方法来设置'条件'矩阵并比较它们,同时忽略在条件无关紧要的元素。
任何提示?
目前我的代码是:
use warnings;
use strict;
#fancy matrix
my @matrix;
#set to a blank 3d test matrix
for my $i (0 .. 6) {
for my $j (0 .. 6) {
for my $k (0 .. 2) {
$matrix[$i][$j][$k] = 0;
}
}
}
#set some values for matrix
for my $j (0..2, 4..6) {
my $i = 4;
for my $k (0 .. 2) {
$matrix[$i][$j][$k] = 1;
}
}
for my $i (0..2, 4..6) {
my $j = 4;
for my $k (0 .. 2) {
$matrix[$i][$j][$k] = 1;
}
}
#the conditional problem child
if ($matrix[0][4][0] == 1 and $matrix[0][4][1] == 1 and $matrix[0][4][2] == 1 and $matrix[1][4][0] == 1 and $matrix[1][4][1] == 1 and $matrix[1][4][2] == 1 and $matrix[2][4][0] == 1 and $matrix[2][4][1] == 1 and $matrix[2][4][2] == 1 and $matrix[4][4][0] == 1 and $matrix[4][4][1] == 1 and $matrix[4][4][2] == 1 and $matrix[5][4][0] == 1 and $matrix[5][4][1] == 1 and $matrix[5][4][2] == 1 and $matrix[6][4][0] == 1 and $matrix[6][4][1] == 1 and $matrix[6][4][2] == 1 and $matrix[4][0][0] == 1 and $matrix[4][0][1] == 1 and $matrix[4][0][2] == 1 and $matrix[4][1][0] == 1 and $matrix[4][1][1] == 1 and $matrix[4][1][2] == 1 and $matrix[4][2][0] == 1 and $matrix[4][2][1] == 1 and $matrix[4][2][2] == 1 and $matrix[4][4][0] == 1 and $matrix[4][4][1] == 1 and $matrix[4][4][2] == 1 and $matrix[4][5][0] == 1 and $matrix[4][5][1] == 1 and $matrix[4][5][2] == 1 and $matrix[4][6][0] == 1 and $matrix[4][6][1] == 1 and $matrix[4][6][2] == 1) {
print "it worked";
}
<stdin>;
编辑注意:如果我接近它的方式是最好的(怀疑它),是否至少有一种方法可以使if条件可读(不是36在单行上进行比较)?
答案 0 :(得分:2)
使更具可读性(但速度不快)的一种方法是使用Test::Deep's Test::Deep::NoTest中的eq_deeply
。
你传递了两个数据结构,它告诉你它们是否相等。如果你只知道结构的一半,你可以使用漂亮的辅助函数来忽略它的一部分。
use Test::Deep::NoTest;
my $equal = eq_deeply( $matrix,
[
[
[ 1, 0, ],
[ 0, 0, ],
],
[
[ 1, 1, ],
[ 0, 1, ],
],
[
[ 1, 1, ],
[ 0, 1, ],
],
]
);
if ($equal) {
# ...
}
答案 1 :(得分:1)
我建议您构建一个对子集中所有矩阵元素的引用数组。然后,您可以在简单的package com.secrethq.ads;
import java.lang.ref.WeakReference;
import org.cocos2dx.lib.Cocos2dxActivity;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.seth.slex.show.PTPlayer;
import com.seth.slex.show.R;
import com.google.android.gms.ads.*;
public class PTAdAdMobBridge {
private static final String TAG = "PTAdAdMobBridge";
private static Cocos2dxActivity activity;
private static WeakReference<Cocos2dxActivity> s_activity;
private static AdView adView;
private static InterstitialAd interstitial;
private static LinearLayout layout;
private static boolean isScheduledForShow;
private static native void interstitialDidFail();
private static native void bannerDidFail();
public static void initBridge(Cocos2dxActivity activity){
Log.v(TAG, "PTAdAdMobBridge -- INIT");
isScheduledForShow = false;
PTAdAdMobBridge.s_activity = new WeakReference<Cocos2dxActivity>(activity);
PTAdAdMobBridge.activity = activity;
PTAdAdMobBridge.initBanner();
PTAdAdMobBridge.initInterstitial();
}
public static void initBanner(){
Log.v(TAG, "PTAdAdMobBridge -- initBanner");
PTAdAdMobBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
if(PTAdAdMobBridge.adView != null){
return;
}
FrameLayout frameLayout = (FrameLayout)PTAdAdMobBridge.activity.findViewById(android.R.id.content);
RelativeLayout layout = new RelativeLayout( PTAdAdMobBridge.activity );
frameLayout.addView( layout );
RelativeLayout.LayoutParams adViewParams = new RelativeLayout.LayoutParams(
AdView.LayoutParams.WRAP_CONTENT,
AdView.LayoutParams.WRAP_CONTENT);
adViewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
adViewParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
PTAdAdMobBridge.adView = new AdView( PTAdAdMobBridge.activity );
PTAdAdMobBridge.adView.setAdSize(AdSize.SMART_BANNER);
PTAdAdMobBridge.adView.setAdUnitId(activity.getResources().getString(R.string.admob_id_banner_admob));
layout.addView(PTAdAdMobBridge.adView, adViewParams);
PTAdAdMobBridge.adView.setVisibility( View.INVISIBLE );
AdRequest adRequest = new AdRequest.Builder().build();
PTAdAdMobBridge.adView.loadAd( adRequest );
}
});
}
public static boolean isBannerVisible(){
if(PTAdAdMobBridge.adView == null){
return false;
}
else{
if(PTAdAdMobBridge.adView.getVisibility() == View.VISIBLE){
return true;
}
else{
return false;
}
}
}
public static void initInterstitial(){
Log.v(TAG, "PTAdAdMobBridge -- initInterstitial");
PTAdAdMobBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
if(PTAdAdMobBridge.interstitial != null){
return;
}
AdRequest adRequest = new AdRequest.Builder().build();
PTAdAdMobBridge.interstitial = new InterstitialAd( PTAdAdMobBridge.activity );
String admobid = activity.getResources().getString(R.string.admob_id_interstitial_admob);
PTAdAdMobBridge.interstitial.setAdUnitId(admobid);
if(PTPlayer.setContentView != null)PTPlayer.setContentView.setId(admobid);
PTAdAdMobBridge.interstitial.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
if(PTAdAdMobBridge.isScheduledForShow){
PTAdAdMobBridge.showFullScreen();
}
}
@Override
public void onAdClosed() {
AdRequest adRequest = new AdRequest.Builder().build();
PTAdAdMobBridge.interstitial.loadAd(adRequest);
}
@Override
public void onAdFailedToLoad(int errorCode) {
PTAdAdMobBridge.interstitialDidFail();
}
});
PTAdAdMobBridge.interstitial.loadAd(adRequest);
}
});
}
public static void showFullScreen(){
Log.v(TAG, "showFullScreen");
if(PTAdAdMobBridge.interstitial != null){
PTAdAdMobBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
if(PTAdAdMobBridge.interstitial.isLoaded()){
if(PTPlayer.is()){
if(PTPlayer.wait){
PTPlayer.wait = false;
PTAdAdMobBridge.interstitial.show();
PTAdAdMobBridge.isScheduledForShow = false;
}else{
PTPlayer.setContentView();
PTPlayer.wait = true;
}
}else{
PTAdAdMobBridge.interstitial.show();
PTAdAdMobBridge.isScheduledForShow = false;
}
}
else{
PTAdAdMobBridge.isScheduledForShow = true;
}
}
});
}
}
public static void showBannerAd(){
Log.v(TAG, "showBannerAd");
if(PTAdAdMobBridge.adView != null){
PTAdAdMobBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
AdRequest adRequest = new AdRequest.Builder().build();
PTAdAdMobBridge.adView.loadAd(adRequest);
PTAdAdMobBridge.adView.setAdListener(new AdListener() {
@Override
public void onAdFailedToLoad(int errorCode) {
PTAdAdMobBridge.bannerDidFail();
}
});
PTAdAdMobBridge.adView.setVisibility( View.VISIBLE );
}
});
}
}
public static void hideBannerAd(){
Log.v(TAG, "hideBannerAd");
if(PTAdAdMobBridge.adView != null){
PTAdAdMobBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
PTAdAdMobBridge.adView.setVisibility( View.INVISIBLE );
}
});
}
}
}
循环中设置和测试它们
这里我的引用数组称为for
。我还使用了来自List::Util
的@cells
函数,该函数允许在一次调用中进行所有测试,并且一旦测试失败就会短路
all
答案 2 :(得分:1)
使用List::MoreUtils
(或List::AllUtils
)中的map
和all
,您可以缩短条件:
use List::MoreUtils 'all';
if ( all { $_ == 1 } map { @{ $matrix[$_][4] }, @{ $matrix[4][$_] } } 0..2, 4..6 ) {
say "It worked!";
}
如果您不熟悉perl中的地图和解除引用语法,则看起来有点令人困惑。 map
创建了matrix[0..2,4..6][4]
和matrix[4][0..2,4..6]
条目的列表。然后将所有这些值传递给all
块,该块检查所有接收的值是否等于1.
因为matrix[n][n]
会返回ARRAY引用,所以你必须取消引用它,例如。 @{ $array_ref }