I have an array that looks like this:
var myArray = [ "name1+data1" , "name2+data2" , "name3+data3", "name4+data4" ]
When the user enters name1, I would like to open an alert box and display data1, for name2 it should display data2, and so on.
In order to do this, I was wondering how I could split all the strings without using more than one array? And how do I display only data1 when name1 is entered by the user?
I’ve tried using myArray.split("+") but it does not work.
You could map the splitted strings and get an object form the key/value pairs.
var array = ['name1+data1', 'name2+data2', 'name3+data3', 'name4+data4'],
object = Object.fromEntries(array.map(s => s.split('+')));
console.log(object);
You could try implementing below function that takes two arguments.
targetArray is the array to perform search and searchString is the string to search. In your case searchString would be name1. The time complexity is based on the position of the element in the array O(K).
function findMatch(targetArray, searchString) {
const targetElement = targetArray.find(item => {
const leftSplit = item.split('+')[0];
return leftSplit === searchString;
});
if (targetElement) {
return targetElement.split('+')[1];
} else {
return null;
}
}
window.alert(
findMatch([ "name1+data1" , "name2+data2" , "name3+data3", "name4+data4" ], 'name2')
);
Alerts: "data2"
If it is an array, then you need to iterate through the array.
const output = myArray.filter(arrayItem => arrayItem.includes(userInput))[0].split('+')[0];
The time complexity here would be O(N+M), where N is length of array and M is the length of the string.
I think it would be better if myArray is maintained as a dictionary,
const myArray = {
name1: 'data1',
name2: 'data2',
name3: 'data3'
}
const output = myArray[userInput];
The time complexity would be decreased to O(1)
You could use this snippet
var myArray = [ "name1+data1" , "name2+data2" , "name3+data3", "name4+data4" ];
var userValue = prompt('Valeur à rechercher...');
myArray.map((item) => {
if(~item.search(userValue) && userValue.length > 0){
alert(item.split('+')[1]);
return false;
}
})
So, here's an example where name1 and name2 have values, but not the others:
let pairs = [ "name1+data1" , "name2+data2" , "name3+", "name4+" ]
We can split each of those into two-element arrays:
let arr = pairs.map(p=>p.split('+'))
And filter out the ones with empty names:
arr = arr.filter(a=>a[1].length > 0)
arr.join("\n") // "name1,data1
// name2,data2"
Does that do what you want?
Related
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)
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 have to following array:
var arr1 = [
[{n:"0.1",m:"m.0",other:"eg1"}],
[{n:"1.1",m:"m.1",other:"eg2"}],
[{n:"2.1",m:"m.2",other:"eg3"}]
];
And I would like to convert it to an array of arrays, as follows:
var arr1 = [
["0.1","0"],
["1.1","1"],
["2.1","2"]
];
I would like to convert to the other array only a few properties, not all of them.
Any idea how I can do this?
PS: I was using flatMap from another post but it does not work as it does not exist in Edge.
Assuming that the second value in each subarray is coming from the number after the period from the m key, you could use the map function to accomplish this:
var arr1 = [
[{n:"0.1",m:"m.0",other:"eg1"}],
[{n:"1.1",m:"m.1",other:"eg2"}],
[{n:"2.1",m:"m.2",other:"eg3"}]
];
var newArray = arr1.map(x => [x[0].n, x[0].m.split('.')[1]]);
console.log(newArray);
For next time you have to put your attempts.
this is the solution for your problem
var arr1 = [
[{n:"0.1",m:"m.0",other:"eg1"}],
[{n:"1.1",m:"m.1",other:"eg2"}],
[{n:"2.1",m:"m.2",other:"eg3"}]
];
arr1 = arr1.map(currentArray=>{
const item = currentArray.shift();
return [item.n,item.m.replace( /^\D+/g, '')]
});
I have an array set up like the following:
var array = [["A1", "left:81px"], ["A2", "left:145px"],...]
The purpose of this is to take a user input and search through this array to find the location to move an element to. If the user input is "A1" how can I parse through this array to set some variable equal to "left:81px"?
Use find and some simple destructuring.
var array = [
["A1", "left:81px"],
["A2", "left:145px"]
];
const [, res] = array.find(([k]) => k == "A1") || [];
console.log(res);
The above returns undefined if no value is found.
Slightly simpler code:
var array = [
["A1", "left:81px"],
["A2", "left:145px"]
];
const input = "A1";
let res = "";
for (let i = 0; i < array.length; i++) {
if (array[i][0] == input) {
res = array[i][1];
break;
}
}
console.log(res);
Assuming that the inner arrays are always structured like [key, value]:
// this is your array.
const array = [["A1", "left:81px"], ["A2", "left:145px"]]
// user input:
const query = "A1";
// find an inner array in array whose first element matches the user input
const [, result] = array.find(([key]) => key === query) || []
console.log(result);
If possible, you should use a better (map-like) data structure for this:
const data = {
A1: 'left:81px',
A2: 'left:145px'
};
const query = 'A1';
const result = data[query];
console.log(result);
The array version has a linear runtime where as the second one is constant time. If you will do this lookup often, it is worth converting your array representation to an object
To achieve expected result, use Object.fromEntries to convert key ,value pair array to object - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
Convert key-value pairs array to object using Object.fromEntries.
Find value using key value like A1,A2
working code sample
var arr = [["A1", "left:81px"], ["A2", "left:145px"]]
function findVal(word, arr){
var obj = Object.fromEntries(arr)
return obj[word]
}
console.log(findVal('A1', arr))
Option 2: Using reduce and converting key ,value pair array to object one time and use for further searches everytime and also for better browser compatibility compare to Object.fromEntries
var arr = [["A1", "left:81px"], ["A2", "left:145px"]]
var obj = arr.reduce((acc,v)=>{
acc[v[0]] = v[1]
return acc
}, {})
console.log(obj['A1'])
I am trying to compare two different arrays together, One previous and one current. The previous set of data contains:
[
{"member_name":"Test1","item":"Sword"},
{"member_name":"Test2","item":"Sword"}
]
The new set contains:
[
{"member_name":"Test1","item":"Sword"},
{"member_name":"Test2","item":"Sword"},
{"member_name":"Test1","item":"Shield"}
]
So as you can see here Test1 has obtained a new item. I've tried to compare these two arrays together a few ways but with no avail.
The methods I've tried:
This one just returns the entire array. Not individual items.
Items_Curr.filter(function(item) { return !Items_Prev.includes(item); });
This method just returns 3 Undefined's.
Items_Curr.map(e => { e.member_name });
I've been looking through trying to find a way of doing this but other posts just explain methods to determine change in simpler arrays.
E.G [a,b] - [a, b, c]
Update:
The end goal is I'd like to create a new array 'NewItems' which would contain an array of all the newly added names and items. So if there is change, I would like that to be broadcasted, if there is no change, then ignore until the function has been ran again.
Realistically you want to do something like:
[a, b, c] - [a, b]
Which would give you c. You can achieve this using .some, which allows you to "customize" the includes functionality.
See example below:
const arr1 = [
{"member_name":"Test1","item":"Sword"},
{"member_name":"Test2","item":"Sword"}
];
const arr2 = [
{"member_name":"Test1","item":"Sword"},
{"member_name":"Test2","item":"Sword"},
{"member_name":"Test1","item":"Shield"}
];
const res = arr2.filter(({member_name:a, item:x}) => !arr1.some(({member_name:b, item:y}) => a === b && x === y));
console.log(res);
If you know your properties will always be in the same order you can use JSON.stringify to serialize the objects and compare the results:
const Items_Prev = [
{"member_name":"Test1","item":"Sword"},
{"member_name":"Test2","item":"Sword"}
]
const Items_Curr = [
{"member_name":"Test1","item":"Sword"},
{"member_name":"Test2","item":"Sword"},
{"member_name":"Test1","item":"Shield"}
]
const serialized_Items_Prev = Items_Prev.map(i => JSON.stringify(i));
const NewItems = Items_Curr.filter(i => !serialized_Items_Prev.includes(JSON.stringify(i)));
console.log(NewItems);
I think something like this you need to do if keys of objects are not changing and new items are only added at last.
const array1 = [
{"member_name":"Test1","item":"Sword"},
{"member_name":"Test2","item":"Sword"}
];
const array2 = [
{"member_name":"Test1","item":"Sword"},
{"member_name":"Test2","item":"Sword"},
{"member_name":"Test1","item":"Shield"}
];
const compare = (array1, array2) => {
if (array1.length !== array2.length) {
return false;
}
for (let i = 0; i < array1.length; i += 1) {
if (array1[i].member_name !== array2[i].member_name) {
return false;
}
if (array1[i].item !== array2[i].item) {
return false;
}
}
return true;
};
console.log(compare(array1, array2));
If order of objects are changing, then you need to write sorting algo for array and then compare.
You can acheieve it using array methods filter() and findIndex()
Filter current array with out put of findIndex() function on previous array
var prevItems = [
{"member_name":"Test1","item":"Sword"},
{"member_name":"Test2","item":"Sword"}
]
var currItems = [
{"member_name":"Test1","item":"Sword"},
{"member_name":"Test2","item":"Sword"},
{"member_name":"Test1","item":"Shield"},
{"member_name":"Test2","item":"Shield"}
]
var newItems = currItems.filter(function(currItem ){
return prevItems.findIndex(function(prevItem){
return prevItem.member_name == currItem.member_name &&
prevItem.item == currItem.item
}) == -1
})
console.log(newItems)