cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
  • Sign-in to the JMP Community will be unavailable intermittently Dec. 6-7 due to a system update. Thank you for your understanding!
  • We’re retiring the File Exchange at the end of this year. The JMP Marketplace is now your destination for add-ins and extensions.
  • JMP 19 is here! Learn more about the new features.

Discussions

Solve problems, and share tips and tricks with other JMP users.
Choose Language Hide Translation Bar
Voizingu
Level IV

Remove element from a list that contain elements from a second list in JSL

Hello,

 

Removing elements from a list is well documented in the the JSL discussions but for some reason I cannot figure out how to do this:

I need to remove elements from a list if the elements CONTAIN string from another list (not exact match).

 

Example below: I am trying to remove all elements that contain "Cal" or "Blue"

 

Thanks in advance,

 

-Voiz

Names Default To Here( 1 );
clear symbols();
Deletesymbols();

ChosenDataCol = {"Cal1", "Cal2", "Cal3", "Temp1", "Temp25", "Blue56", "Blue32", "Blue95"};

RemoveCol = {"Cal", "Blue"};

For (i=1,i<=N Items( RemoveCol ), i++,
	For (j=N Items (ChosenDataCol), j<=1, j--,
		If(contains(ChosenDataCol[j], Eval(RemoveCol[i]))==1, 
			Remove from(ChosenDataCol, j)
		)
	)
);

show (ChosenDataCol);

 

2 ACCEPTED SOLUTIONS

Accepted Solutions
jthi
Super User

Re: Remove element from a list that contain elements from a second list in JSL

You can also utilize For Each or Filter Each

Names Default To Here(1);

ChosenDataCol = {"Cal1", "Cal2", "Cal3", "Temp1", "Temp25", "Blue56", "Blue32", "Blue95"};
RemoveCol = {"Cal", "Blue"};

vals = Filter Each({val1}, ChosenDataCol,
	res = Filter Each({val2}, RemoveCol,
		!Contains(val1, val2)
	);
	N Items(res) == N Items(RemoveCol);
);

// ChosenDataCol = vals; // {"Temp1", "Temp25"}
-Jarmo

View solution in original post

jthi
Super User

Re: Remove element from a list that contain elements from a second list in JSL

You will also have to consider what N Items(res) == N Items(KeepCol); is doing. You can add extra print inside the loop to assist in figuring that out

Names Default To Here(1);

ChosenDataCol = {"SiCal 1", "Ba Cal 2", "toCal 3", "Si Temp1", "bouTemp25", "CaBlue 56", "SiBlue 32", "Blue 95"};
KeepCol = {"Cal", "Blue"};

vals = Filter Each({val1}, ChosenDataCol,
	res = Filter Each({val2}, KeepCol,
		Contains(val1, val2)
	);
	show(res);
	N Items(res) != N Items(KeepCol);
);

Also if you can have situations where both Cal and Blue can appear in single string, you will need to utilize a bit different method

-Jarmo

View solution in original post

7 REPLIES 7
txnelson
Super User

Re: Remove element from a list that contain elements from a second list in JSL

In your For() loop, 

j<=1

should be

j>=1
Names Default To Here( 1 );
clear symbols();
Deletesymbols();

ChosenDataCol = {"Cal1", "Cal2", "Cal3", "Temp1", "Temp25", "Blue56", "Blue32", "Blue95"};

RemoveCol = {"Cal", "Blue"};

For (i=1,i<=N Items( RemoveCol ), i++,
	For (j=N Items (ChosenDataCol), j>=1, j--,
		If(contains(ChosenDataCol[j], RemoveCol[i])==1, 
			Remove from(ChosenDataCol, j)
		)
	)
);
show (ChosenDataCol);
Jim
Voizingu
Level IV

Re: Remove element from a list that contain elements from a second list in JSL

Hi Jim,

 

Ha yes, I missed that :)

The solution works BUT it seems that the contains() is not very robust: if the String to look is in the middle of the list element, it doesn't find it. 

Do you know why?

The log of the script below gives:

ChosenDataCol = {"Si Cal 1", "Ba Cal 2", "toCal 3", "Temp 1", "Temp 25", "SiBlue 32"};

instead of 

ChosenDataCol = {"Temp 1", "Temp 25"};

 

Names Default To Here( 1 );
clear symbols();
Deletesymbols();

ChosenDataCol = {"Si Cal 1", "Ba Cal 2", "toCal 3", "Temp 1", "Temp 25", "Blue 56", "SiBlue 32", "Blue 95"};

RemoveCol = {"Cal", "Blue"};

For (i=1,i<=N Items( RemoveCol ), i++,
	For (j=N Items (ChosenDataCol), j>=1, j--,
		If(contains(ChosenDataCol[j], Eval(RemoveCol[i]))==1, 
			Remove from(ChosenDataCol, j)
		)
	)
);

show (ChosenDataCol);

Thanks 

txnelson
Super User

Re: Remove element from a list that contain elements from a second list in JSL

Please refer to my initial response JSL.  

Contains( ChosenDataCol[j], Eval( RemoveCol[i] ) ) == 1

was changed to

contains(ChosenDataCol[j], RemoveCol[i])==1

which allows for the correct answer.  I am not sure why the Eval() is interfering with the Contains()

Jim
jthi
Super User

Re: Remove element from a list that contain elements from a second list in JSL

You can also utilize For Each or Filter Each

Names Default To Here(1);

ChosenDataCol = {"Cal1", "Cal2", "Cal3", "Temp1", "Temp25", "Blue56", "Blue32", "Blue95"};
RemoveCol = {"Cal", "Blue"};

vals = Filter Each({val1}, ChosenDataCol,
	res = Filter Each({val2}, RemoveCol,
		!Contains(val1, val2)
	);
	N Items(res) == N Items(RemoveCol);
);

// ChosenDataCol = vals; // {"Temp1", "Temp25"}
-Jarmo
Voizingu
Level IV

Re: Remove element from a list that contain elements from a second list in JSL

Hello Jarmo,

 

Thanks the Filter each () seems to do the trick, even with more intricate inputs (see below).

Ideally I need the options to filter ChosenDataCol with the 2 ways:

- Remove unwanted elements based on list of string (this method here, which works now) => RemoveCol

- Only keep elements based on list of string (the opposite of the method here)

 

I thought removing the "NOT" from "!Contains()" should do the trick but it returns an empty list { }.

 

Do you know why?

 

thanks 

 

Remove elements <-- works well

Names Default To Here(1);

ChosenDataCol = {"SiCal 1", "Ba Cal 2", "toCal 3", "Si Temp1", "bouTemp25", "CaBlue 56", "SiBlue 32", "Blue 95"};
RemoveCol = {"Cal", "Blue"};

vals = Filter Each({val1}, ChosenDataCol,
	res = Filter Each({val2}, RemoveCol,
		!Contains(val1, val2)
	);
	N Items(res) == N Items(RemoveCol);
);

// log : {"Si Temp1", "bouTemp25"}

Keep elements <-- doesn't work

Names Default To Here(1);

ChosenDataCol = {"SiCal 1", "Ba Cal 2", "toCal 3", "Si Temp1", "bouTemp25", "CaBlue 56", "SiBlue 32", "Blue 95"};
KeepCol = {"Cal", "Blue"};

vals = Filter Each({val1}, ChosenDataCol,
	res = Filter Each({val2}, KeepCol,
		Contains(val1, val2)
	);
	N Items(res) == N Items(KeepCol);
);

// log : {}

 

jthi
Super User

Re: Remove element from a list that contain elements from a second list in JSL

You will also have to consider what N Items(res) == N Items(KeepCol); is doing. You can add extra print inside the loop to assist in figuring that out

Names Default To Here(1);

ChosenDataCol = {"SiCal 1", "Ba Cal 2", "toCal 3", "Si Temp1", "bouTemp25", "CaBlue 56", "SiBlue 32", "Blue 95"};
KeepCol = {"Cal", "Blue"};

vals = Filter Each({val1}, ChosenDataCol,
	res = Filter Each({val2}, KeepCol,
		Contains(val1, val2)
	);
	show(res);
	N Items(res) != N Items(KeepCol);
);

Also if you can have situations where both Cal and Blue can appear in single string, you will need to utilize a bit different method

-Jarmo
Voizingu
Level IV

Re: Remove element from a list that contain elements from a second list in JSL

Hello Jarmo,

 

The "show(res)" helped me understand the logic. I really have to use For Each () functions more :)

there was a missing "!" before Contains to make the script really work, but now my 2 functions work properly.

I will have to think about your last remark, not sure if that scenario exists!

 

Thanks again  

 

Voiz

 

Names Default To Here(1);

ChosenDataCol = {"SiCal 1", "Ba Cal 2", "toCal 3", "Si Temp1", "bouTemp25", "CaBlue 56", "SiBlue 32", "Blue 95"};
KeepCol = {"Cal", "Blue"};

vals = Filter Each({val1}, ChosenDataCol,
	res = Filter Each({val2}, KeepCol,
		!Contains(val1, val2)
	);
	N Items(res) != N Items(KeepCol);
);

show(vals)

// vals = {"SiCal 1", "Ba Cal 2", "toCal 3", "CaBlue 56", "SiBlue 32", "Blue 95"};

Recommended Articles