I have multidimensional array, that shown from console.log(temp) in my dashboard.component.ts just like this:
[[],[],[],[],[],[],[],[],[],[],[{"user_id":"ismail.rahman.saanin#gmal.com","status":"Idle"},{"user_id":"lutfi.aldi.nugroho#gmil.com","status":"Overload"}]]
Basically, this kind of array (contain null array inside) is rare condition. But it disturb me, i cant parse the data.
My Dashboard.component.ts
this.scheduleService.getShiftSchedule().subscribe((temp)=>{
this.api = temp;
//console.log(temp);
var ids = [['user_id', 1], ['status', 2]],
result = Object.keys(temp).map(o => ids.map(([key, id]) => ({ id, content: temp[o][key] })));
this.tablePresetData = result;
})
My question is, how to filter data if there is condition null array in multidimensional array like in my case ?
Need Help, Thanks guys...
You can use .filter() and return element .length where 0 evaluates to false
let [res] = array.filter(({length}) => length)
or use .flat()
let res = array.flat()
You can check if length is greater than 0.
let arr = [[],[],[],[],[],[],[],[],[],[],[{"user_id":"ismail.rahman.saanin#gmal.com","status":"Idle"},{"user_id":"lutfi.aldi.nugroho#gmil.com","status":"Overload"}]];
arr = arr.filter(item => Array.isArray(item) && item.length > 0)
console.log(arr);
Related
I need to achieve this result
[['peanuts', 'butter'], ['butter', 'jelly'], ['jelly', 'bananas'], ['bananas', 'apples']]
From this array
[['butter', 'jelly'], ['bananas', 'apples'], ['peanuts', 'butter'], ['jelly', 'bananas']]
I want the second element of each array to match the first element of the next one.
I think sort function is the best option here, but I have tried this and this doesn't work (actually works but not with all arrays somehow)
.sort(([a, b], [c, d]) => {
return b === c ? -1 : 1
})
Sorting is not the best method to solve this problem. Instead, you can create lookup tables for the first and second elements and go through them in sequence.
const arr = [
['butter', 'jelly'],
['bananas', 'apples'],
['peanuts', 'butter'],
['jelly', 'bananas']
];
const lookupFirst = {},
lookupSecond = {};
for (let i = 0; i < arr.length; i++) {
lookupFirst[arr[i][0]] = i;
lookupSecond[arr[i][1]] = i;
}
const next = arr.map(x => lookupFirst[x[1]]);
let curr = arr.findIndex(x => !lookupSecond[x[0]]);
const res = [];
do {
res.push(arr[curr]);
} while ((curr = next[curr]) !== undefined);
console.log(JSON.stringify(res));
Sorting will not help, instead one needs an algorithm which, for instance, starts by searching for the only array that does not have any matching item which links it to any of the other arrays.
This array's first item (a string) then is the link to this very arrays previous array that's last item does match the before mentioned first item.
The above described process splices every matching array from the input value and collects (unshift) them within a result array, thus it mutates the input value, and therefore just needs to be continued until the input value got emptied.
function getCopyInDominoesLikeOrder(list) {
// in order to not directly mutate the input value.
list = Array.from(list);
// get the array where its last item does not match
// any other array's first item, which makes it the
// last array of the return value.
let itemListIndex = list.findIndex(aList =>
list.every(bList => aList[aList.length - 1] !== bList[0])
);
let itemList = list.splice(itemListIndex, 1)[0];
const result = [itemList]; // return value.
let firstItem = itemList[0];
// mutate/reduce the input value's copy while looking
// for the array where its last item matches the first
// item of the previously found/extracted (linked) array.
while (list.length !== 0) {
itemListIndex = list.findIndex(aList =>
aList[aList.length - 1] === firstItem
);
itemList = list.splice(itemListIndex, 1)[0]; // mutate/reduce.
result.unshift(itemList); // aggregate return value.
firstItem = itemList[0];
}
return result;
}
const arr = [
['butter', 'jelly'],
['bananas', 'apples'],
['peanuts', 'butter'],
['jelly', 'bananas'],
];
console.log(
'original :: arr :',
arr
);
console.log(
'sorted :: getCopyInDominoesLikeOrder(arr) :',
getCopyInDominoesLikeOrder(arr)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
It looks like you only need to extract the first element from each array in the sort callback, then return the lexiographic difference:
const arr = [['c','d'], ['a','b'], ['d','e'], ['b','c']];
arr.sort((a, b) => a[0].localeCompare(b[0]));
console.log(arr);
.sort(([a], [b]) => a > b)
I have an array of array, how to find if a value exists inside this array in javascript. Here is the code example
let multival = [['Individual'], ['Non-Individual'],null]
Now I have to find if string 'Non-Individual' is present in this array of array or not, can anyone have solution in this regards
You could use Array.prototype.some() to check the string is present in the array of array.
const multival = [['Individual'], ['Non-Individual'], null];
const searchItem = 'Non-Individual';
const ret = multival.some(
(x) => Array.isArray(x) && x.some((y) => y === searchItem)
);
console.log(ret);
Out of interest, a recursive solution for arrays with any level of nested depth (And I believe quicker than a solution using flat() due to short circuiting):
function nestedIncludes(arr, val) {
let check = i => Array.isArray(i) ? i.some(check) : i === val;
return arr.some(check);
}
let myArr = [[[['foo'],1],2],3,5];
let test = nestedIncludes(myArr, 'foo');
console.log(test); // true
Try flat and includes function:
const multival = [['Individual'], ['Non-Individual'],null]
const exists = multival.flat().includes('Non-Individual');
console.log(exists ? 'exists' : 'non-exists')
Note: I didn't notice, but User863 comment with the same answer.
Method 1, Using findIndex, optional chaining and includes
Method 2, Using some, optional chaining and includes
// Method 1, Using `findIndex` and `includes`
const find = (arr, item) => arr.findIndex((arr2) => arr2?.includes(item)) > -1;
// Method 2, Using `some` and `includes`
const find2 = (arr, item) => arr.some((arr2) => arr2?.includes(item));
let multival = [["Individual"], ["Non-Individual"], null];
console.log(find(multival, "Individual"));
console.log(find2(multival, "Individual"));
console.log(find(multival, ""));
console.log(find2(multival, ""));
I am trying to get multiple index positions on an Array for a Boolean value.
I have tried applying a loop using while and for to iterate more then one index position with no success so far.
Here is my code:
let jo = [1,2,3,4,5]
let ji = [1,2,3]
let checker = (arr1,arr2) => {
let falsy = arr1.every(num => arr2.includes(num)) == false ?
arr1.map(falsy => arr2.includes(falsy)) : "tba";
//the block below is the frustrated attempt:
let i = falsy.indexOf(false);
while(i>=0){
return falsy.findIndex(ih => ih == false)
}
}
console.log(checker(jo,ji))
I would like to get the index where false occurs stored in a variable that has iterated over all array so I can use this variable to return just the false values on falsy like this:
return falsy[i] = [4,5]
Then after that I will add more to the first if statement to check both arr1 x arr2 or arr2 x arr1
Thanks in advance!
It looks like you're attempting to get the difference between two arrays. This is a fairly comment use-case for Sets. In this case, your code would look like this:
let jo = [1,2,3,4,5]
let ji = [1,2,3]
const checker = (arr1, arr2) => {
return new Set(arr1.filter(x => !new Set(arr2).has(x)))
}
console.log(checker(jo, ji)); // {4, 5}
If you wanted to get the indexes of the differences, you would need to apply a map to the result of the new Set like so:
const checker = (arr1, arr2) => {
const difference = new Set(arr1.filter(x => !new Set(arr2).has(x)));
return Array.from(difference).map(value => arr1.indexOf(v));
}
I’m trying to map a nested array and return the words that have more letters than 6, I have been stuck for a while with this problem so I’d like to get some help
const array = [["hellow",'pastas'],["travel", "militarie"],["oranges","mint"]]
const arrayOne = array.map(new => new).filter(arr =>arr.length > 6)
You can flat array first and than filter out words with length greater than 6
const array = [['hellow','pastas'],['travel', 'militaries'],['oranges','mint']]
const arrayOne = array.flat(1).filter(e=> e.length > 6 )
console.log(arrayOne)
You can use the code below. This code uses .map() and .filter() to check if the length is greater than 6, and adds it to the array if it is.
const array = [["hellow","pastas"],["travel", "militarie"],["oranges","mint"]];
const arrayOne = array.map(e1 => e1.filter(e2 => e2.length > 6)).flat();
console.log(arrayOne);
I think better will be the filter() method instead.
array.filter(function (c) {
return c.length < 6;
});
But first use the flat() method.
There are many ways to do it.
You can use flatMap and filter:
const array = [['hellow','pastas'],['travel', 'militarie'],['oranges','mint']];
const result = array.flatMap(x => x.filter(y => y.length > 6));
console.log(result);
Another way is to use reduce and filter:
const array = [['hellow','pastas'],['travel', 'militarie'],['oranges','mint']];
const result = array.reduce((acc, x) => [...acc, ...x.filter(y => y.length > 6)], []);
console.log(result);
I have a multidimensional object array that I need to update by comparing to an object array. I flattened out the multidimensional array and did a nested for each loop. I am getting duplicate results and I can not figure out what I am doing wrong.
const newSections = [[{"id":9141118,"name":"cxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"593f35e7-c5b4-4c79-b4b8-0cc34dfd76a4"},{"id":9143204,"name":"cxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9785f527-0c1f-414f-bd6b-9416da90a24f"}],[{"id":9141118,"name":" xzcxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"b6a78cf9-0de1-4465-bf7b-02b221330fcb"},{"id":9143204,"name":" xzcxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9ef10b9b-b143-48a2-8e4f-fc2fdad4788b"}]]
const section = [{"id":9141118,"name":"cxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":"32","fut":0,"con":0,"tot":32,"storeTot":1,"variance":31,"uid":"593f35e7-c5b4-4c79-b4b8-0cc34dfd76a4"},{"id":9143204,"name":"cxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9785f527-0c1f-414f-bd6b-9416da90a24f"}]
let myNewArray = [].concat.apply([], newSections)
let result = []
_.each(myNewArray, item => {
_.each(section, sec => {
if (item.uid === sec.uid) result.push(sec)
else result.push(item)
})
})
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
You can use find to avoid a nested loop (and that solves your duplication bug):
const newSections = [[{"id":9141118,"name":"cxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"593f35e7-c5b4-4c79-b4b8-0cc34dfd76a4"},{"id":9143204,"name":"cxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9785f527-0c1f-414f-bd6b-9416da90a24f"}],[{"id":9141118,"name":" xzcxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"b6a78cf9-0de1-4465-bf7b-02b221330fcb"},{"id":9143204,"name":" xzcxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9ef10b9b-b143-48a2-8e4f-fc2fdad4788b"}]]
const section = [{"id":9141118,"name":"cxz","qtr":"12/2016","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":"32","fut":0,"con":0,"tot":32,"storeTot":1,"variance":31,"uid":"593f35e7-c5b4-4c79-b4b8-0cc34dfd76a4"},{"id":9143204,"name":"cxz","qtr":"03/2017","min":0,"max":0,"occ":0,"mod":0,"fv":0,"uc":0,"vdl":0,"fut":0,"con":0,"tot":0,"storeTot":1,"variance":-1,"uid":"9785f527-0c1f-414f-bd6b-9416da90a24f"}]
let myNewArray = [].concat.apply([], newSections)
let result = []
_.each(myNewArray, item => {
let newItem = section.find((sec) => item.uid === sec.uid)
result.push(newItem || item)
});
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
there is a logic error I think, you are loading elements of both array into your result array. you should skip pushing if (item.uid === sec.uid) result.push(sec) if ID matches.