I am struggling at the moment with making a new array of strings from another array that I have to filter for certain pattern.
Example:
let originalString = "4162416245/OG74656489/OG465477378/NW4124124124/NW41246654"
I guess this could be matched from this string as well. But my initial approach was to split this string at each / :
let splitArr = originalString.split('/');
// splitArr = ["4162416245", "OG74656489", "OG465477378", "NW4124124124", "NW41246654"]
Basically what I do have to achieve is to have 2 different array that is filtered down by pattern of the start of this strings. OG and NW is always fix won't change but numbers after I don't know.. Backend sends this data as OG(original ticket) NW(new ticket) so those prefixes are fix, I have to check for string starting with them and put them in they array:
ogArr = ["OG74656489", "OG465477378"]
nwArr = ["NW4124124124", "NW41246654"]
If you want 2 separate arrays, you can use filter and startsWith
let originalString = "4162416245/OG74656489/OG465477378/NW4124124124/NW41246654";
let splitArr = originalString.split('/');
const ogArr = splitArr.filter(s => s.startsWith("OG"));
const nwArr = splitArr.filter(s => s.startsWith("NW"));
console.log(ogArr);
console.log(nwArr);
Another option could be using reduce to travel the collection once, and pass in an object with 2 properties where you can extract the data from.
let originalString = "4162416245/OG74656489/OG465477378/NW4124124124/NW41246654";
let splitArr = originalString.split('/');
const res = splitArr.reduce((acc, curr) => {
if (curr.startsWith("OG")) acc.og.push(curr)
if (curr.startsWith("NW")) acc.nw.push(curr)
return acc;
}, {
"nw": [],
"og": []
})
console.log(res);
You can also use the Array.prototype.reduce() method to add the elements into an object containing all tickets.
This would lead to this results :
{
"OG": [
"OG74656489",
"OG465477378"
],
"NW": [
"NW4124124124",
"NW41246654"
]
}
let originalString = "4162416245/OG74656489/OG465477378/NW4124124124/NW41246654"
const tickets = originalString.split('/').reduce((acc, curr) => {
if(curr.startsWith('OG')) acc["OG"].push(curr)
else if(curr.startsWith('NW')) acc["NW"].push(curr)
return acc
}, {OG: [], NW: []})
console.log(tickets)
Related
I was trying to compare 2 different api calls from which i am able to make out 2 different arrays of ids , So i am trying to filter out the ids which already exist in array2 , and for the remaining ids i am trying to set the state , could anyone help me with it ?
code so far :
const [ prevAdmins , setPrevAdmins ] = useState<any>([]);
const [options, setOptions] = useState([{value: "", label: ""}]);
//API 1 CALL
get_user_groups({bot_id:params.botid , group_id:params.userid}).then((res) => {
setDetails(res?.data?.data[0]);
setGroupName(res?.data?.data[0].name)
let prevAdmins: any = [];
res?.data?.data[0]?.join_details.map((prevJoinee , idx) => {
prevAdmins.push(prevJoinee.user_id)
setPrevAdmins(prevAdmins)
})
});
//OUTPUT FOR API 1 "prevAdmins": ['61dfcfb71f492f4f4f589e93', '61dedd23bd15322626dd7539']
//2nd API CALL :
get_followers({bot_id:params.botid}).then((res) => {
if(res.data.data){
let option: any = [];
let allAdmins: any = [];
res.data.data.map((admin, index) => {
allAdmins.push(admin._id);
if(!prevAdmins.includes(allAdmins)){
option.push({value: admin._id, label: admin.displayName})
}
})
setOptions(option);
}
})
//OUTPUT FOR API 2 : ['61dfd02a1f492f4f4f589f00', '61dfcfb71f492f4f4f589e93', '61dedd23bd15322626dd7539']
Now what i am trying is to exclude the ids which is already present in Array 1 and setOptions should store the ids which are not excluded.
Regards !
If you want to get the unique values form your api calls, You can use Set instead of an array.
Please refer: https://www.javatpoint.com/typescript-set
You can use spread operator to combine two arrays and then convert it to Set and make an array from that Set. It will be unique.
roughly you can do something similar to this approach.
let array1 = [1,2,4]
let array2 = [4,3,5,6]
let combinedArray = [...array1, ...array2]
let arraySet = new Set(combinedArray)
let uniqueArray = Array.from(arraySet)
console.log(uniqueArray)
spread operator will combine two arrays but it will have duplicate values too.
when you convert it into Set, it will remove any duplicate values.
Then you can simply generate an array from that Set variable.
You can do this to make it short too.
let uniqueArray = Array.from(new Set([...array1, ...array2]))
after you have the unique array you can simply set state with the uniqueArray variable.
In your case:
if you are getting these two arrays.
let arr1 = ['61dfcfb71f492f4f4f589e93', '61dedd23bd15322626dd7539']
let arr2 =['61dfd02a1f492f4f4f589f00', '61dfcfb71f492f4f4f589e93', '61dedd23bd15322626dd7539']
you can do something like this
let uniqueArray = Array.from(new Set([...arr1, ...arr2]))
console.log(uniqueArray)
I would like some assistance to remove duplicates and remove the | and the '' at the start and end.
My code so far
const thedates = this.results
.filter((result) => result.thedate)
.map((item) => item.thedate)
.filter((thedate, i, arr) => arr.indexOf(thedate) === i);
// Split multiple thedates in strings and store in an array
let thedate = [];
thedates.forEach((item) => {
const splitArr = item.split(", ");
thedate = thedate.concat(splitArr).sort();
});
// Filter again for unique thedates
this.thedates = thedate.filter(
(thedate, i, arr) => arr.indexOf(thedate) === i
);
My output in the console from the code above
'full-time', 'full-time|full-time', 'full-time|full-time|full-time', 'full-time|full-time|full-time|full-time', 'full-time|full-time|part-time|full-time|part-time|part-time',
I would just like each entry to say: full-time, part-time or full-time if there is just one between the quotes.
Can anyone help to add to my code please?
You're essentially asking two things, how to turn a delimited string into array and how to remove duplicate values from an array. You can parse by using the .split() method, and remove duplicates from an array by constructing a set with it then turning it back into an array with the spread operator.
Altogether (where array is your input array):
let filteredArray = [ ...new Set( string.split( '|') ) ]
const string = "full-time|part-time|full-time|part-time|full-time|part-time|full-time|part-time|full-time|part-time|full-time|part-time|part-time|full-time|full-time|part-time|full-time|part-time|full-time|full-time|part-time|part-time";
let filteredArray = [ ...new Set( string.split( '|') ) ]
let result = filteredArray.join(', ');
console.log(result)
You could try something like this (similar to #Julien Mellon's post) where you use .split(), but you return an array of arrays with the second level array being the entry:
const thedates = ['full-time', 'full-time|part-time', 'full-time|part-time|full-time', 'full-time|full-time|part-time|full-time', 'full-time|full-time|part-time|full-time|part-time|part-time']
const theDatesFormatted = thedates.map(item => {
const arr = item.split('|')
const uniqueArr = [...new Set(arr)]
return uniqueArr
})
console.log(theDatesFormatted)
if your inputs are
'full-time', 'full-time|full-time', 'full-time|full-time|full-time', 'full-time|full-time|full-time|full-time', 'full-time|full-time|part-time|full-time|part-time|part-time'
perhaps you could just call .split('|') ?
so I want to find unique values from an array.
so for example I have this array:
const mainArr = ['shape-10983', 'size-2364', 'size-7800', 'size-4602', 'shape-11073', 'size-15027', 'size-15030', 'size-15033', 'height-3399', 'height-5884']
so I want to find the first matching value for each unique item.
for example, in the array, I have two strings with the shape prefix, six items with the size prefix, and two items with the height prefix.
so I want to output to be something like
const requiredVal = ["shape-10983", "size-2364", "height-3399"]
I want only the first value from any set of different values.
the simplest solution will be to iterate on the list and storing what you got in a dictionary
function removeSimilars(input) {
let values = {};
for (let value of input) {//iterate on the array
let key = value.splitOnLast('-')[0];//get the prefix
if (!(key in values))//if we haven't encounter the prefix yet
values[key] = value;//store that the first encounter with the prefix is with 'value'
}
return Object.values(values);//return all the values of the map 'values'
}
a shorter version will be this:
function removeSimilars(input) {
let values = {};
for (let value of input)
values[value.splitOnLast('-')[0]] ??= value;
return Object.values(values);
}
You could split the string and get the type and use it aks key for an object along with the original string as value. At result take only the values from the object.
const
data = ['shape-10983', 'size-2364', 'size-7800', 'size-4602', 'shape-11073', 'size-15027', 'size-15030', 'size-15033', 'height-3399', 'height-5884'],
result = Object.values(data.reduce((r, s) => {
const [type] = s.split('-', 1);
r[type] ??= s;
return r;
}, {}));
console.log(result);
If, as you mentioned in the comments, you have the list of prefixes already available, then all you have to do is iterate over those, to find each first element that starts with that prefix in your full list of possible values:
const prefixes = ['shape', 'size', 'height'];
const list = ['shape-10983', 'size-2364', 'size-7800', 'size-4602', 'shape-11073', 'size-15027', 'size-15030', 'size-15033', 'height-3399', 'height-5884']
function reduceTheOptions(list = [], prefixes = [], uniques = []) {
prefixes.forEach(prefix =>
uniques.push(
list.find(e => e.startsWith(prefix))
)
);
return uniques;
}
console.log(reduceTheOptions(list, prefixes));
Try this:
function getRandomSet(arr, ...prefix)
{
// the final values are load into the array result variable
result = [];
const randomItem = (array) => array[Math.floor(Math.random() * array.length)];
prefix.forEach((pre) => {
result.push(randomItem(arr.filter((par) => String(par).startsWith(pre))));
});
return result;
}
const mainArr = ['shape-10983', 'size-2364', 'size-7800', 'size-4602', 'shape-11073', 'size-15027', 'size-15030', 'size-15033', 'height-3399', 'height-5884'];
console.log("Random values: ", getRandomSet(mainArr, "shape", "size", "height"));
I modified the #ofek 's answer a bit. cuz for some reason the ??= is not working in react project.
function removeSimilars(input) {
let values = {};
for (let value of input)
if (!values[value.split("-")[0]]) {
values[value.split("-")[0]] = value;
}
return Object.values(values);
}
create a new array and loop over the first array and check the existing of element before in each iteration if not push it to the new array
I am trying to split an array of integers into an array of arrays by duplicate values. The original array is composed of a list of 6 digit integers, some of these integers come in pairs, others come in groups of 3 or 4s. I'd like to get these duplicates pushed to their own arrays and have all of these arrays of duplicates composed into an array of arrays that I can later loop through.
I've looked on in the lodash library for some method or combination of but can't quite find anything that seems to work. I've also tried a few different configurations with nested for loops but also am struggling with that.
const directory = "X/";
let files = fs.readdirSync(directory);
let first6Array = [ ];
for(i=0; i< files.length; i++){
let first6 = files[i].substring(0, 6);
first6Array.push(first6);
};
console.log(first6Array);
example output of first6Array:
[ '141848',
'141848',
'141848',
'142851',
'142851',
'143275',
'143275']
I'd like to end up with something like
let MasterArray = [[141848,141848,141848],[142851,142851],[143275,143275]];
You can use new Set() to filter out the duplicates.
Then you use the unique Array and filter for every value.
const firstArray = [ '141848', '141848', '141848', '142851', '142851', '143275', '143275'];
const numberArray = firstArray.map(Number);
const masterArray = [];
const unique = new Set (numberArray); // Set {141848, 142851, 143275}
unique.forEach(u => {
masterArray.push(numberArray.filter(e => e === u));
});
console.log(masterArray);
Using lodash, you can create a function with flow:
map the items by truncating them and converting to numbers.
groupBy the value (the default).
convert to an array of arrays using values.
const { flow, partialRight: pr, map, truncate, groupBy, values } = _;
const truncate6 = s => truncate(s, { length: 6, omission: '' });
const fn = flow(
pr(map, flow(truncate6, Number)),
groupBy,
values,
);
const firstArray = [ '141848abc', '141848efg', '141848hij', '142851klm', '142851opq', '143275rst', '143275uvw'];
const result = fn(firstArray);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Use reduce to create an object of arrays, indexed by number, and push to the associated array on each iteration (creating the array at the key first if needed), then get the values of the object:
const directory = "X/";
const files = fs.readdirSync(directory);
const output = Object.values(
files.reduce((a, file) => {
const num = Number(file.slice(0, 6));
if (!a[num]) a[num] = [];
a[num].push(num);
return a;
}, {})
);
It's pretty weird to have an array of identical values, though - you might consider a different data structure like
{
'141848': 3,
'142851': 2
}
to keep track of the number of occurrences of each number:
const output = files.reduce((a, file) => {
const num = file.slice(0, 6);
a[num] = (a[num] || 0) + 1;
return a;
}, {})
To obtain exactly the result you desire, you need a nested find, something like this should works:
const directory = "X/";
let files = fs.readdirSync(directory);
let first6Array = files.reduce((acc, value)=> {
let n = +value.substr(0, 6); // assumes it can't be NaN
let arr = acc.find(nested => nested.find(item => item === n));
if (arr) {
arr.push(n);
} else {
acc.push([n]);
}
return acc;
}, []);
console.log(first6Array);
Notice that an hashmap instead, with the value and the number of occurrence, would be better, also in term of performance, but I don't think it mind since you have really few elements.
Also, it assumes the first six characters are actually numbers, otherwise the conversion would fail and you'll get NaN.
It would be safer adding a check to skip this scenario:
let n = +value.substr(0, 6);
if (isNaN(n)) {
return acc;
}
// etc
In my JS project, I am using Lodash library to Extract property, split array, get unique values.
var taskobj = [
{'taskno':'a', 'team':'1,2'},
{'taskno':'b', 'team':'3,4'},
{'taskno':'c', 'team':'2,4'},
];
//Looping through the object to convert string to array
_.forEach(taskobj, function(value, key) {
taskobj[key].team = _.split(taskobj[key].team,',');
});
// using _.map to extract team and return array
// using _.flatten to flatten array
// using _.uniq to get unique values from flattned array.
return _.uniq(_.flatten(_.map(taskobj,'team')));
// logs - [1,2,3,4]
Is this the most efficient way to achieve this?
you can use reduce and start with a new Set() and add the values of team every time ( then convert it back to an array with the spread operator )
var taskobj = [
{'taskno':'a', 'team':'1,2'},
{'taskno':'b', 'team':'3,4'},
{'taskno':'c', 'team':'2,4'},
];
var result = [...taskobj.reduce((acc, {team}) => {
team.split(',').forEach(e => acc.add(e))
return acc
}, new Set())]
console.log(result)
This can be achieved by using lodash#flatMap with an iteratee that splits the team string into an array, which is then flattened by the mentioned function and then use lodash#uniq to get the final result.
var result = _.uniq(_.flatMap(taskobj, ({ team }) => team.split(',')));
var taskobj = [
{'taskno':'a', 'team':'1,2'},
{'taskno':'b', 'team':'3,4'},
{'taskno':'c', 'team':'2,4'},
];
var result = _.uniq(_.flatMap(taskobj, ({ team }) => team.split(',')));
console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
Use simpler version
try this
var teams = [];
var taskobj = [
{'taskno':'a', 'team':'1,2'},
{'taskno':'b', 'team':'3,4'},
{'taskno':'c', 'team':'2,4'},
];
taskobj.map(obj => {
var teamSplit = obj.team.split(',');
teams = [...teams, ...teamSplit];
})
var uniqTeams = _.uniq(teams);
console.log('teams', teams);
console.log('uniqTeams', uniqTeams)
JsBin link
http://jsbin.com/bedawatira/edit?js,console