I have an array of strings :
let arr = ["cap:1", "col:red", "cap:3", "cap:1", "col:blue", "screen:yes"]
and I want to have a new array, with one item from each category of substrings("cap", "col", "screen"),the one with smallest index:
let newArray = ["cap:1","col:red","screen:yes"]
//"cap:1" from newArray is arr[0]
I tried this way:
const newArr = (arr) => {
let c= []
let c = [...c, arr[0]]
for(let i = 1; i<arr.length; i++){
for (let j=0; j<c.length; j++){
if(arr[i].split(":")[0] !== c[j].split(":")){
c = [...c, arr[i]]
}
}
}
return c
}
but it goes into infinite loop and the result is something like this: ["cap:1","col:red","col:red","col:red","col:red","col:red","col:red","col:red"...
Could you please help me?
Thanks!
Your logic has no way of determining that the current element's prefix was not found in newArr. Also, in the condition arr[i].split(":")[0] !== c[j].split(":") you are comparing a string to an array, which always returns true - string !== array.
May be you intended to write arr[i].split(":")[0] !== c[j].split(":")[0] which would still not give you the desired result.
You can do away with the inner loop and check each element against newArr using c.every(el => !...) as follows:
let arr = ["cap:1", "col:red", "cap:3", "cap:1", "col:blue", "screen:yes"];
const newArr = (arr) => {
let c = [arr[0]];
for(let i = 1; i<arr.length; i++) {
if( c.every(el => !arr[i].startsWith( el.split(':')[0] )) ) {
c = [ ...c, arr[i] ];
}
}
return c;
}
console.log( newArr( arr ) );
It goes on infinite loop since there are two nested for loop and one of the nested for loop is iterating an ever increasing array. Instead you can have an object which will be act as a reference.
let arr = ["cap:1", "col:red", "cap:3", "cap:1", "col:blue", "screen:yes"];
const newArr = (arr) => {
let c = [];
const suffixObj = {};
for (let i = 0; i < arr.length; i++) {
const getPrefix = arr[i].split(":")[0];
if (!suffixObj.hasOwnProperty(getPrefix)) {
c.push(arr[i]);
suffixObj[getPrefix] = true
}
}
return c
};
console.log(newArr(arr))