我正在寻找distinct
的反面。
在包含[ "a", "a", "b", "c", "b", "d" ]
的列表中,我只想保留"a"
和"b"
,因为它们会多次出现。
解决方法可能如下:
val similarsList = mutableListOf<String>()
list.filter {
if (similars.contains(it))
return@filter true
similars.add(it)
false
}.distinct()
这将删除与之前已包含的元素匹配的每个元素。在list
对象中,所有出现多次的元素都将存储在filter
之后。在这种情况下,distinct
会清除出现过三次或更多次的元素。
我正在寻找一种惯用的方式正是这样做的,与distinct
相反。
答案 0 :(得分:13)
使用Kotlin 1.1标准库中引入的API,@gil.fernandes可以对.groupingBy { ... }
提供的解决方案进行小改进:Grouping
。它不是立即创建组,而是创建一个惰性.eachCount()
,然后可以查询它。特别是,我们可以要求{{3}},它返回Map<T, Int>
:
val l = listOf("a", "a", "b", "c", "b", "d")
val result = l.groupingBy { it }.eachCount().filterValues { it > 1 }.keys
它比使用.groupBy { ... }
更有效,因为它不会将列存储在列表中。
答案 1 :(得分:7)
如果您想过滤掉重复项(非不同项目),可以尝试:
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.HashMap;
import java.util.Map;
public class PersonalDetailsFragment extends Fragment {
// Code variables
boolean male = true;
boolean radioButtonSelected = false;
String firstName;
String initials;
String lastName;
String current_uid;
// Layout Fields
private TextInputLayout mFirstName;
private TextInputLayout mInitials;
private TextInputLayout mLastName;
private Button mContinueBtn;
private RadioButton mFemale;
private RadioButton mMale;
//Firebase Auth
private FirebaseAuth mAuth;
private DatabaseReference mUserDatabase;
private FirebaseUser mCurrentUser;
//ProgressDialog
private ProgressDialog mProgressDialog;
// View Pager
private ViewPager mViewPager;
// View
View view;
public PersonalDetailsFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_personal_details, container, false);
// Button(s) Initialisation
mContinueBtn = (Button) view.findViewById(R.id.btnContinue);
// Firebase Initialisation
mAuth = FirebaseAuth.getInstance();
mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
current_uid = mCurrentUser.getUid();
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(current_uid);
mUserDatabase.keepSynced(true);
// Progress Bar Initialisation
mProgressDialog = new ProgressDialog(getActivity());
// View Pager Initialisation
mViewPager = (ViewPager) getActivity().findViewById(R.id.main_tabPager);
// Layout fields Initialisation
mFirstName = (TextInputLayout) view.findViewById(R.id.inputFirstName);
mInitials = (TextInputLayout) view.findViewById(R.id.inputInitials);
mLastName = (TextInputLayout) view.findViewById(R.id.inputLastName);
mUserDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (FirebaseDatabase.getInstance().getReference().child("Users").child("first_name") == null)
{
String ofirst_name = dataSnapshot.child("first_name").getValue().toString();
mFirstName.getEditText().setText(ofirst_name);
}// end of if
if (FirebaseDatabase.getInstance().getReference().child("Users").child("initials") == null)
{
String oinitials = dataSnapshot.child("initials").getValue().toString();
mInitials.getEditText().setText(oinitials);
}// end of if
if (FirebaseDatabase.getInstance().getReference().child("Users").child("last_name") == null)
{
String olast_name = dataSnapshot.child("last_name").getValue().toString();
mLastName.getEditText().setText(olast_name);
}// end of if
} // end of onDataChange ()
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
mContinueBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
firstName = mFirstName.getEditText().getText().toString();
initials = mInitials.getEditText().getText().toString();
lastName = mLastName.getEditText().getText().toString();
if ( TextUtils.isEmpty( firstName ) || TextUtils.isEmpty( initials ) || TextUtils.isEmpty( lastName ) || radioButtonSelected == false )
{
Toast.makeText( getActivity().getApplicationContext(), "Make sure all fields are filled in.", Toast.LENGTH_LONG ).show();
} else {
mProgressDialog.setTitle("Saving Details");
mProgressDialog.setMessage("Please wait while we save your details...");
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
update_user();
} // end of if
} // end of onClick
}); // end of mContinueBtn.setOnClickListener
// Declaring and Initialising radio buttons
final RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.gender);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.radioMale:
male = true;
radioButtonSelected = true;
break;
case R.id.radioFemale:
male = false;
radioButtonSelected = true;
break;
} // end of switch statement
} // end of onCheckedChanged
}); // end of radioGroup.setOnCheckedChangeListener
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// save views as variables in this method
// "view" is the one returned from onCreateView
// Android Fields
}
private void update_user() {
Map update_hashMap = new HashMap();
update_hashMap.put("first_name", firstName);
update_hashMap.put("last_name", lastName);
update_hashMap.put("initials", initials);
mUserDatabase.setValue(update_hashMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
mProgressDialog.dismiss();
mViewPager.setCurrentItem(1);
Toast.makeText(getActivity().getApplicationContext(), "Success Uploading.", Toast.LENGTH_LONG).show();
}
}
});
} // end of update_user
}
打印出来:
fun main(args: Array<String>) {
val l = listOf( "a", "a", "b", "c", "b", "d" )
println(l.groupBy { it }.filter { it.value.size > 1 }.keys)
}
说明:[a, b]
生成包含此内容的分组地图:
l.groupBy { it }
然后将过滤器应用于此地图,按值(列表)过滤,其长度优先于1:{a=[a, a], b=[b, b], c=[c], d=[d]}
。
最后,使用filter { it.value.size > 1 }
提取密钥。
答案 2 :(得分:0)
我看到这个问题已经得到了回答,但以防万一有人正在寻找比使用组更有效的方法。
哪里可以这样做
import numpy as np
def encode_state(state):
a=0
for i,num in enumerate(state.reshape(9)) :
a = a + 3**i * int(num)
return a.to_bytes(2,'big')
def decode_state(byte):
encoded_value = int.from_bytes(byte,'big')
b = [0 for i in range(9)]
for i in range(9) :
num = (encoded_value // 3**i) % 3
b[i] = num
return np.array(b).reshape(3,3)
input_state = np.array((
(2, 2, 2),
(1, 2, 2),
(2, 1, 0)),
dtype="int32")
state_as_byte = encode_state(input_state)
output_state = decode_state(state_as_byte)
print (''.join('{:02x}'.format(x) for x in state_as_byte))
print(output_state)
虽然这完全有效,但如果您需要效率,最好只使用 for 循环和 HashSets
从我的测试中我发现这更有效、更快
val list = listOf(0,1,2,3,4,5,0)
//Gives you group of duplicated numbers. In this case just 0
val group = list.groupBy{it}.filter{it.values.size>1}.keys