How can I search for an element within a nested array. Following is what the array looks like
arr = [
["choice1", ['a', [2, 4]], ['b', [1, 3, 4]], ['c', [3, 4]]],
["choice2", ['b', [1, 4]], ['c', [1, 3]]],
["choice3", ['b', [1, 2, 4]], ['c', [1, 2, 3, 4]]]
]
if 'a' is equal to '2' then the following function has to return "choice1" and "choice3" in the 'result':
function arraySearch(arr, a) {
var result = [];
for(var i = 0; i < arr.length; i++) {
// compare each arr[i] with 'a' for the very first occurrence, and move the next array
if(arr[i].search(a)){
result.concat(arr[0]);
}
}
return result;
}
Please help. Many thanks in advance.
something like
arr = [
["choice1", ['a', [2, 4]], ['b', [1, 3, 4]], ['c', [3, 4]]],
["choice2", ['b', [1, 4]], ['c', [1, 3]]],
["choice3", ['b', [1, 2, 4]], ['c', [1, 2, 3, 4]]]
];
find = function(arr, a) {
var found = [];
var foundCurrent;
// for each 'choice'
for (var choice = 0; choice < arr.length; choice++) {
foundCurrent = false;
// look at each entry in the array that is arr[current][1]
for (var entry = 1; entry < arr[choice].length; entry++) {
// search these for the value
if (arr[choice][entry][1].indexOf(a) != -1) {
if (!foundCurrent) {
found[found.length] = arr[choice][0];
}
foundCurrent = true;
}
}
}
return found;
};
find(arr, 2);
>> [choice1, choice3]
It's not clear to me exactly what you need.
If you want to know whether an array contains an element, use Array.indexOf.
Related
I want to write a code in javascript to convert a nested array in to a nested object. The point is every single elements in the nested array would be an array itself, so should convert to a nested object:
Examples:
[['a', 1], ['b', 2], ['c', [['d', 4]]]] => { a: 1, b: 2, c: { d: 4 } }
[['a', 1], ['b', 2], ['c', [['d', [['e', 5], ['f', 6]]]]]]
=> { a: 1, b: 2, c: { d: { e: 5, f: 6 } } }
I tried to go with this concept:
define a function to iterate over the base array. for every single element, it will make a key:value for the object. if the value is an array, the function will call itself.
but Actually I dont know how to write it.
const nestedArrayToObject = function (arr) {
let obj = {};
for (let i = 0; i < arr.length; i++) {
let key = arr[i][0];
let val = arr[i][1];
if (!Array.isArray(val)) {
obj[key] = val;
} else {
nestedArrayToObject(val); ???
}
}
return obj;
};
You can use Object.fromEntries to convert an array of key-value pairs to an object. For each value that is also an array, recursively call the conversion function.
function convert(arr) {
return Object.fromEntries(arr.map(([k, v]) =>
[k, Array.isArray(v) ? convert(v) : v]));
}
console.log(convert([['a', 1], ['b', 2], ['c', [['d', 4]]]]));
console.log(convert([['a', 1], ['b', 2], ['c', [['d', [['e', 5], ['f', 6]]]]]]));
Let's say I have the following two-dimensional array:
const array = [[1, 1], [1, 2], [2, 1], [2, 2]];
What I want to do is to find all the values under first index which have common zero index value. So the result should be the following:
[[1, [1, 2]], [2, [1, 2]]]
Or maybe Map would look better:
[Map(1 => [1, 2]), Map(2 => [1, 2])]
How can I do that? With or without lodash. My solution looks a bit bloated and messy:
const array = [[1, 1], [1, 2], [2, 1], [2, 2]];
const grouppedCartItemsMap = new Map();
array.forEach((item) => {
const [locationId, contractId] = item;
if (!grouppedCartItemsMap.has(locationId)) {
grouppedCartItemsMap.set(locationId, [contractId]);
} else {
const existingItem = grouppedCartItemsMap.get(locationId);
if (!existingItem.includes(contractId)) {
grouppedCartItemsMap.set(locationId, [...existingItem, contractId]);
}
}
});
console.log(grouppedCartItemsMap);
If an object would work:
const array = [[1, 1], [1, 2], [2, 1], [2, 2]];
const grouped = {};
for (const [first, last] of array) {
grouped[first] ??= [];
grouped[first].push(last);
}
console.log(grouped);
This looks like a use case for reduce:
const array = [[1, 1], [1, 2], [2, 1], [2, 2]];
const grouppedCartItemsMap = array.reduce((acc, [locationId, contractId]) => {
if (!acc.has(locationId)) acc.set(locationId, [contractId]);
else acc.get(locationId).push(contractId);
return acc;
}, new Map());
console.log([...grouppedCartItemsMap.entries()]);
I am wondering how you would go about deleting arrays that contain the same elements in a 2 dimensional array.
For example:
let 2dArr = [ [1, 2, 3],
[3, 2, 1],
[2, 4, 5],
[4, 5, 2],
[4, 3, 1] ];
This array would delete the second and fourth elements, returning the 2d array:
returnedArr = [ [1, 2, 3],
[2, 4, 5],
[4, 3, 1] ];
How exactly could this be done, preserving the 2d array? I could only think to loop through elements, comparing elements via a sort, and deleting them as you go along, but this would result in an indexing error if an element is deleted.
1) You can easily achieve the result using reduce and Set as:
let twodArr = [
[1, 2, 3],
[3, 2, 1],
[2, 4, 5],
[4, 5, 2],
[4, 3, 1],
];
const set = new Set();
const result = twodArr.reduce((acc, curr) => {
const key = [...curr].sort((a, b) => a - b).join();
if (!set.has(key)) {
set.add(key);
acc.push(curr);
}
return acc;
}, []);
console.log(result);
2) You can also use filter as:
let twodArr = [
[1, 2, 3],
[3, 2, 1],
[2, 4, 5],
[4, 5, 2],
[4, 3, 1],
];
const set = new Set();
const result = twodArr.filter((curr) => {
const key = [...curr].sort((a, b) => a - b).join();
return !set.has(key) ? (set.add(key), true) : false;
});
console.log(result);
const seen = []
const res = array.filter((item) => {
let key = item.sort().join()
if(!seen.includes(key)){
seen.push(key)
return item
}
})
console.log(res)
You can use hash map
let arr = [ [1, 2, 3], [3, 2, 1],[2, 4, 5],[4, 5, 2],[4, 3, 1] ];
let obj = {}
let final = []
for(let i=0; i<arr.length; i++){
// create a key
let sorted = [...arr[i]].sort((a,b)=> a- b).join`,`
// check if this is not present in our hash map
// add value to final out and update hash map accordingly
if(!obj[sorted]){
obj[sorted] = true
final.push(arr[i])
}
}
console.log(final)
Using Array.prototype.filter() and a Set as thisArg
let arr = [ [1, 2, 3],
[3, 2, 1],
[2, 4, 5],
[4, 5, 2],
[4, 3, 1] ];
let res = arr.filter(function(e){
const sorted = [...e].sort((a,b) => a-b).join('|');
return this.has(sorted) ? false : this.add(sorted)
},new Set)
console.log(res)
This question already has answers here:
How to find all subsets of a set in JavaScript? (Powerset of array)
(14 answers)
Closed 2 years ago.
Question is basically to generate all subsets given an array of unique integers.
For example powerSet[1,2,3] should return [[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]
Here is my recursive attempt:
function powerset(array) {
// Write your code here.
let set = [[]];
powersetHelper(array, [], set);
return set;
}
function powersetHelper(array, subset, set) {
if (array.length === 0) return;
for (let i = 0; i < array.length; i++) {
subset.push(array[i]);
set.push(subset);
}
let newArr = array.slice(1);
powersetHelper(newArr, [], set)
}
Why is this returning [[], [1, 2, 3], [1, 2, 3], [1, 2, 3], [2, 3], [2, 3], [3]] instead of the correct solution?
Additionally, I have attempted this iteratively as follows:
function powerset(array) {
// Write your code here.
let subset = [];
let set = [[]];
while (array.length > 0) {
for (let j = 0; j < array.length; j++) {
let num = array[j];
subset.push(num);
set.push(subset);
}
array = array.slice(1);
}
return set;
}
This is also incorrect and somehow returning what I have below even though it seems to be the same logic as my recursive solution
[
[],
[1, 2, 3, 2, 3, 3],
[1, 2, 3, 2, 3, 3],
[1, 2, 3, 2, 3, 3],
[1, 2, 3, 2, 3, 3],
[1, 2, 3, 2, 3, 3],
[1, 2, 3, 2, 3, 3]
]
You need to take a copy without object reference.
function powerSet(array) {
// Write your code here.
let set = [[]];
powersetHelper(array, [], set);
return set;
}
function powersetHelper(array, subset, set) {
if (array.length === 0) return;
for (let i = 0; i < array.length; i++) {
subset.push(array[i]);
set.push([...subset]); // take copy without object reference
}
let newArr = array.slice(1);
powersetHelper(newArr, [], set)
}
console.log(powerSet([1, 2, 3])); // [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
.as-console-wrapper { max-height: 100% !important; top: 0; }
Second one, with the same problem
function powerSet(array) {
// Write your code here.
let subset = [];
let set = [[]];
while (array.length > 0) {
for (let j = 0; j < array.length; j++) {
let num = array[j];
subset.push(num);
set.push([...subset]);
}
array = array.slice(1);
}
return set;
}
console.log(powerSet([1, 2, 3])); // [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
.as-console-wrapper { max-height: 100% !important; top: 0; }
For example, if I want to check whether arr1 (an array of 3 arrays) contains any element of arr2 (an array of 2 arrays), I use the .some() function, but it returns false.
let arr1 = [[1, 2], [2, 3], [3, 4]]
let arr2 = [[1, 2], [5, 2],]
if (arr1.some(x => arr2.includes(x))) {
alert('arr1 has arr2')
};
x does return the array [1, 2], but for some reason it doesn't pass the check for .some() in arr1.
.includes will return true if the passed item is === to one in the array, but separate objects are never === to each other in JS unless one was created from a reference from the other:
const arr = [1, 2];
console.log(arr === [1, 2]);
const arr2 = arr; // same reference
console.log(arr === arr2);
. I suppose one method would be to stringify the subarrays first:
let arr1 = [[1, 2], [2, 3], [3, 4]]
let arr2 = [[1, 2], [5, 2],]
if (arr1.some((subarr1) => {
const str1 = JSON.stringify(subarr1);
return arr2.some(subarr2 => JSON.stringify(subarr2) === str1);
})) {
console.log('arr1 has arr2')
}
I think includes function isn't working for arrays 2 dimension
Please change code like this
let arr1 = [[1, 2], [2, 3], [3, 4]]
let arr2 = [[1, 2], [5, 2],]
if (arr1.some(x => {
return arr2.some(item => item.toString() === x.toString())
})) {
alert('arr1 has arr2')
};
You can you _.isEqualof lodash to compare the Array.
let arr1 = [[1, 2], [2, 3], [3, 4]]
let arr2 = [[1, 2], [5, 2]]
if (arr1.some(x => {
return arr2.some(item => _.isEqual(item, x))
})) {
console.log('arr1 has arr2')
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>