我是新来的,在编写函数destroyer()
以从数组中删除多个值时需要一些帮助。
destroyer()函数传入一个数组,并将其他数字作为参数传递。我们的想法是从数组中删除数字。
E.g。
destroyer([1, 2, 3, 1, 2, 3], 2, 3)
输出:[1, 1]
destroyer(["tree", "hamburger", 53], "tree", 53)
输出:["hamburger"]
destroyer([2, 3, 2, 3], 2, 3)
输出:[]
注意:示例仅显示要删除的2个附加数字。但是函数destroyer()应该能够删除任意数量的值(即4个,5个或6个参数)。
但是,我的代码不会产生相同的结果。具体来说,使用console.log,我发现我的过滤器功能没有正确循环。
1)任何人都可以帮我调试吗?
2)有没有更好的方法来编写这个函数?
非常感谢!!!
function destroyer() {
var args = Array.prototype.slice.call(arguments);
var itemToRemove = args.slice(1);
console.log(itemToRemove);
var newArr = args[0];
console.log(newArr);
function filterer(value) {
for (var i = 0; i < itemToRemove.length; i++) {
console.log(i);
console.log(itemToRemove[i]);
if (value != itemToRemove[i]) {
return value;
}
}
}
return newArr.filter(filterer);
}
答案 0 :(得分:4)
您的filterer
功能可以更加简单:
function filterer (value) {
return itemToRemove.indexOf(value) === -1;
}
答案 1 :(得分:0)
在时间复杂度方面,与对象属性查找相比,使用Array.prototype.indexOf()
可能效率低下。我建议一次循环其他参数并构造一个目标元素作为键被销毁的对象。然后,您可以在传递给Array.prototype.filter()
的过滤回调中检查给定值是否为目标。
function destroyer() {
var arr = arguments.length && arguments[0] || [];
var targets = {};
for (var i = 1; i < arguments.length; i++) {
targets[arguments[i]] = true;
}
return arr.filter(function (x) {
return targets[x] === undefined;
});
}
这种方法的一个缺点是,并非JS中的所有值都可以是对象的有效属性,因为属性必须是字符串。在这种情况下,您只是使用数字作为键,这些数字被隐式转换为字符串。
答案 2 :(得分:0)
我们可以在filter()方法中将参数传递给我们的回调函数。
function destroyer(arr) {
return arr.filter(filterer(arguments)); // Pass arguments
}
function filterer(args) {
return function(value) { // Actual filter function
for (var i = 1; i < args.length; i++) {
if (value === args[i]) // Seek
return false; // Destroy
}
return true; // Otherwise keep
};
}
这传递了 freeCodeCamp |的所有5个测试用例基本算法脚本|寻求和摧毁。
答案 3 :(得分:-1)
以下代码将从数组中删除元素。它删除的元素由任何额外参数定义。 ...remove
是一项ES6功能,可将额外参数聚合到单个数组中。
我将迭代...remove
数组并从我们正在处理的主数组中删除该元素。
这是一个JSFiddle:https://jsfiddle.net/zzyopnnp/
大多数浏览器都不支持 ...extra_parameters
,您可能需要使用arguments
对象。
function removeIndex(array, index) {if(index>-1){array.splice(index, 1);}}
function destroyer(array, ...remove) {
remove.forEach(function(elem, index) {
removeIndex(array, index);
});
};
var arr = ["tree", "hamburger", 53];
destroyer(arr, "tree", 53);
console.log(arr);
答案 4 :(得分:-1)
一个简单的功能
public class SampleAdapter extends RecyclerView.Adapter<SampleAdapter.ViewHolder> {
// Declaring Variable to Understand which View is being worked on
// IF the view under inflation and population is header or Item
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private static final int TYPE_FOOTER = 2;
private Activity mContext;
private ArrayList<DataModel> _mItems;
private int mLayout;
private String mProductHeadingTitle="Heading";
private String mProductHeadingSubTitle="SubHeading";
private String loadingText="LOADING";
private int visibility= View.VISIBLE;
public interface SampleAdapterInterface {
void itemClicked(int position);
}
SampleAdapterInterface mCallBack;
public SampleAdapter(Activity context, ArrayList<DataModel> items, int item_layout) {
if (_mItems != null) {
_mItems.clear();
}
this.mContext = context;
this._mItems = items;
this.mLayout = item_layout;
mCallBack = (SampleAdapterInterface) context;
}
@Override
public int getItemCount() {
return _mItems.size()+2; // +2 for header and footer
}
@Override
public int getItemViewType(int position) {
if (position==0)
return TYPE_HEADER;
else if(position==(_mItems.size()+1))
return TYPE_FOOTER;
return TYPE_ITEM;
}
public void setHeaderData(String title,String subTitle)
{
this.mProductHeadingTitle=title;
this.mProductHeadingSubTitle=subTitle;
Log.d("LOG", "ProductHeadingTitle: " + mProductHeadingTitle);
Log.d("LOG", "ProductHeadingSubTitle: " + mProductHeadingSubTitle);
notifyDataSetChanged();
}
public void setFooterData(String loadingText,int visibility)
{
this.loadingText=loadingText;
this.visibility=visibility;
Log.d("LOG", "LoadingText: " + loadingText);
Log.d("LOG", "Visibility: " + visibility);
notifyDataSetChanged();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_layout,parent,false);
ViewHolder vhHeader = new ViewHolder(view,viewType);
return vhHeader;
}
else if (viewType == TYPE_ITEM)
{
View view = LayoutInflater.from(parent.getContext()).inflate(mLayout,parent,false);
//Creating ViewHolder and passing the object of type view
ViewHolder vhItem = new ViewHolder(view,viewType);
return vhItem;
}
else if (viewType == TYPE_FOOTER)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.footer_lyout,parent,false);
ViewHolder vhFooter = new ViewHolder(view,viewType);
return vhFooter;
}
return null;
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int pos) {
if(viewHolder.Holderid ==0)
{
// header view
Log.d("LOG", "in header binder");
viewHolder.mProductCatalogTitle.setText(mProductHeadingTitle);
viewHolder.mProductCatalogSubTitle.setText(mProductHeadingSubTitle);
}
else if(viewHolder.Holderid==1)
{
final int position=pos-1; // -1 to substract header number
// your code
}
else if(viewHolder.Holderid==2)
{
// footer
Log.d("LOG", "in footer binder");
viewHolder.mProgressBar.setVisibility(visibility);
viewHolder.mLoading.setText(loadingText);
}
}
class ViewHolder extends RecyclerView.ViewHolder {
int Holderid;
// header
TextView mProductCatalogTitle;
TextView mProductCatalogSubTitle;
//list
// item type variable declaration
// footer
ProgressBar mProgressBar;
TextView mLoading;
public ViewHolder(View itemView, int viewType) {
super(itemView);
// Here we set the appropriate view in accordance with the the view type as passed when the holder object is created
if(viewType == TYPE_HEADER)
{
Holderid = 0;
mProductCatalogTitle = (TextView) itemView.findViewById(R.id.tv_title);
mProductCatalogSubTitle = (TextView) itemView.findViewById(R.id.tv_subtitle);
}
else if(viewType == TYPE_ITEM)
{
Holderid = 1;
itemView.setClickable(true);
itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mCallBack.itemClicked(getAdapterPosition()-1);
}
});
// initialize the view holder
}
else if(viewType == TYPE_FOOTER)
{
Holderid = 2;
mLoading = (TextView) itemView.findViewById(R.id.tv_loading);
mProgressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar);
}
}
}
答案 5 :(得分:-1)
对于多个参数
一个简单的功能
function filter(){
var j = -1;
for(var i = 1; i < arguments.length; i++){
j = arguments[0].indexOf(arguments[i]);
if(j > -1){
arguments[0].splice(j, 1);
}
}
return arguments[0];
}
你可以在没有args的情况下调用这个函数 例如:
filter([1,2,3,4,5,6,7,8,9], 1, 3, 5); //return [2,4,6,7,8,9]
filter([1,2,3,4,5,6,7,8,9], 1); //return [2,3,4,5,6,7,8,9]
答案 6 :(得分:-1)
这里确实有很好的答案,但是你可以用这种方式做得非常干净,记住你在过滤方法中有一个对象选项可以在回调函数中使用,在这种情况下我会像使用它一样: arguments [i] 所以我可以检查arguments数组中的每个值
function destroyer(arr) {
for(var i = 1; i < arguments.length; i++){
arr = arr.filter(isIn, arguments[i]);
}
function isIn(element,index, array){
if (element != this){
return element;
}
}
return arr;
}