These all are the tags which I'm storing into in an array with those who have Type_ as a prefix
My array have multiple type of values but I'm unable to sort them here is the array
{
Type_5000-10000mAh: [10, "5000-10000mAh", "type_5000-10000mah", "Type_5000-10000mAh", 70],
Type_15000-20000mAh: [1, "15000-20000mAh", "type_15000-20000mah", "Type_15000-20000mAh", 76],
Type_USB-C: [4, "20000-30000mAh", "type_20000-30000mah", "Type_20000-30000mAh", 95],
Type_20000-30000mAh: [4, "20000-30000mAh", "type_20000-30000mah", "Type_20000-30000mAh", 95],
Type_Wireless: [3, "Wireless", "type_wireless", "Type_Wireless", 160],
Type_Quick Charger: [1, "Quick Charger", "type_quick-charger", "Type_Quick Charger", 344]
}
and the output I want is like that
{
Type_5000-10000mAh: [10, "5000-10000mAh", "type_5000-10000mah", "Type_5000-10000mAh", 70],
Type_15000-20000mAh: [1, "15000-20000mAh", "type_15000-20000mah", "Type_15000-20000mAh", 76],
Type_20000-30000mAh: [4, "20000-30000mAh", "type_20000-30000mah", "Type_20000-30000mAh", 95],
Type_USB-C: [4, "20000-30000mAh", "type_20000-30000mah", "Type_20000-30000mAh", 95],
Type_Wireless: [3, "Wireless", "type_wireless", "Type_Wireless", 160],
Type_Quick Charger: [1, "Quick Charger", "type_quick-charger", "Type_Quick Charger", 344]
}
and this is the code I'm using to get this array format
var tags_type = {};
var indexI = 0;
$.each(totPro.products, (productsKey, productsValue) => {
$.each(productsValue.tags, (prodKey, prodVal) => {
indexI++;
if(prodVal.toLowerCase().indexOf('type') > -1){
console.log(prodVal);
if(tags_type[prodVal] == undefined){
tags_type[prodVal] = [0, capitalizeFirstLetter(prodVal.slice(5)), prodVal.toLowerCase().replace(/\s+/g, '-').toLowerCase(), prodVal, indexI];
}
tags_type[prodVal][0]++;
}
});
});
console.log(tags_type);
You do NOT have an array.
you have an object where you cannot determine the sort order.
You CAN sort the keys and then display the object in that order using localeCompare
Here is a more elaborate explanation: Sort JavaScript object by key
const obj = {
"Type_5000-10000mAh": [10, "5000-10000mAh", "type_5000-10000mah", "Type_5000-10000mAh", 70],
"Type_15000-20000mAh": [1, "15000-20000mAh", "type_15000-20000mah", "Type_15000-20000mAh", 76],
"Type_USB-C": [4, "20000-30000mAh", "type_20000-30000mah", "Type_20000-30000mAh", 95],
"Type_20000-30000mAh": [4, "20000-30000mAh", "type_20000-30000mah", "Type_20000-30000mAh", 95],
"Type_Wireless": [3, "Wireless", "type_wireless", "Type_Wireless", 160],
"Type_Quick Charger": [1, "Quick Charger", "type_quick-charger", "Type_Quick Charger", 344]
}
const sortAlphaNum = (a, b) => a.localeCompare(b, 'en', { numeric: true });
const showObj = obj => Object.keys(obj).sort(sortAlphaNum).forEach(key => console.log(key,obj[key]));
showObj(obj)
If you really want to have a sorted object, then here is a rewrite from the link I posted
const obj = {
"Type_5000-10000mAh": [10, "5000-10000mAh", "type_5000-10000mah", "Type_5000-10000mAh", 70],
"Type_15000-20000mAh": [1, "15000-20000mAh", "type_15000-20000mah", "Type_15000-20000mAh", 76],
"Type_USB-C": [4, "20000-30000mAh", "type_20000-30000mah", "Type_20000-30000mAh", 95],
"Type_20000-30000mAh": [4, "20000-30000mAh", "type_20000-30000mah", "Type_20000-30000mAh", 95],
"Type_Wireless": [3, "Wireless", "type_wireless", "Type_Wireless", 160],
"Type_Quick Charger": [1, "Quick Charger", "type_quick-charger", "Type_Quick Charger", 344]
}
const sortAlphaNum = (a, b) => a.localeCompare(b, 'en', { numeric: true });
const sortedObj = Object.keys(obj)
.sort(sortAlphaNum)
.reduce((acc, key) => { acc[key] = obj[key]; return acc; },{});
console.log(sortedObj)
Mplungian is right in saying that the order of keys in objects is not specified to be preserved in JavaScript. But having said this, many JS implementations do return the keys in the order they were generated. So, maybe you get lucky with the following:
const o={ "Type_5000-10000mAh": [10, "5000-10000mAh", "type_5000-10000mah", "Type_5000-10000mAh", 70], "Type_15000-20000mAh": [1, "15000-20000mAh", "type_15000-20000mah", "Type_15000-20000mAh", 76], "Type_USB-C": [4, "20000-30000mAh", "type_20000-30000mah", "Type_20000-30000mAh", 95], "Type_20000-30000mAh": [4, "20000-30000mAh", "type_20000-30000mah", "Type_20000-30000mAh", 95], "Type_Wireless": [3, "Wireless", "type_wireless", "Type_Wireless", 160], "Type_Quick Charger": [1, "Quick Charger", "type_quick-charger", "Type_Quick Charger", 344] };
const pr=s=>s.replace(/\_(\d+)/,(_,m)=>"_"+m.padStart(5,"0"));
p=Object.fromEntries(
Object.entries(o).sort(([a],[b])=>
pr(a).localeCompare(pr(b))) );
console.log(p)
p is a newly created object where the keys have been added in the desired order.
#mplungians comparison version (with {numeric:true}) will of course work here just as well!
Related
I have an object like this:
const arrays = {
one: [[1, 33, 41], [2, 0, 27], [3, 7, 9], [4, 1, 3]],
two: [[1, 77, 2], [2, 6, 3], [3, 0, 0], [4, 55, 3]],
three: [[1, 4, 6], [2, 0, 0], [3, 5, 6], [4, 0, 0]],
};
As you can see each first number is equal:
1 for each first inner array
2 for each second inner array
3 for each third inner array
etc...
I want to filter based on the first number of each array
and some comparator number e.g. [3]
If we have a filter number [3] (smaller or equal to 3),
the wanted result would be:
const arrays = {
one: [[1,33,41], [2,0,27], [3,7,9]],
two: [[1,77,2], [2,6,3], [3,0,0]],
three: [[1,4,6], [2,0,0], [3,5,6]],
};
Since all first numbers of inner arrays are smaller than or equal to 3.
The arrays starting with 4,5... are ignored.
What would be the ramda's way to have this functionality?
I like Ramda's map function because it can iterate over the properties of an object (and so avoid Object.fromEntries & Object.entries) and apply a function to each one of them. That function is filter which will take as argument the inner arrays. The function given to filter is itself a composition of gte and head; takes the first element of an array and compare it with 3:
const arrays =
{ one: [[1, 33, 41], [2, 0, 27], [3, 7, 9], [4, 1, 3]]
, two: [[1, 77, 2], [2, 6, 3], [3, 0, 0], [4, 55, 3]]
, three: [[1, 4, 6], [2, 0, 0], [3, 5, 6], [4, 0, 0]] };
map(filter(compose(gte(3), head)), arrays);
// ^ ^ ^ ^ ^
// A B C D E
//=> { one: [[ 1, 33, 41], [2, 0, 27], [3, 7, 9]]
//=> , two: [[ 1, 77, 2], [2, 6, 3], [3, 0, 0]]
//=> , three: [[ 1, 4, 6], [2, 0, 0], [3, 5, 6]] }
map over each property (A); each array is passed to filter (B)
Each inner array is passed to compose (C)
Take the head of each inner array (E) and compare with 3 (D)
Scott Christopher rightly pointed out in the comments that gte can be confusing when partially applied. In fact the whole composition can be replaced with this simple lambda: ([x]) => x <= 3.
Alternative solution which I like too:
map(filter(([x]) => x <= 3), arrays);
I'd totally subscribe for #customcommander's approach,
just wanted to add that you can also pass numerical indexes to R.propSatisfies.
const headIs3OrBelow = R.propSatisfies(R.gte(3), 0);
const fn = R.map(R.filter(headIs3OrBelow));
// ===
const data = {
one: [[1, 33, 41], [2, 0, 27], [3, 7, 9], [4, 1, 3]],
two: [[1, 77, 2], [2, 6, 3], [3, 0, 0], [4, 55, 3]],
three: [[1, 4, 6], [2, 0, 0], [3, 5, 6], [4, 0, 0]],
};
console.log(
fn(data),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Also agree that gte and other similar methods are very difficult to read, because they kind of read backwards as is 3 gte than x... in Haskell you could do something like:
3 `gte` x
Vanilla approach:
const headIs3OrBelow = ([head]) => head <= 3;
const fn = (data) => Object.entries(data).reduce(
(res, [k, lists]) => ({ ...res, [k]: lists.filter(headIs3OrBelow) }),
{},
);
// ===
const data = {
one: [[1, 33, 41], [2, 0, 27], [3, 7, 9], [4, 1, 3]],
two: [[1, 77, 2], [2, 6, 3], [3, 0, 0], [4, 55, 3]],
three: [[1, 4, 6], [2, 0, 0], [3, 5, 6], [4, 0, 0]],
};
console.log(
fn(data),
);
I understand you would like to use Ramda, this is not a solution using the library but accomplishes the same. You could create an object from entries that are filtered by comparing the first array value a[0] to the maxVal passed to the function.
const arrays = {
one: [[1, 33, 41], [2, 0, 27], [3, 7, 9], [4, 1, 3]],
two: [[1, 77, 2], [2, 6, 3], [3, 0, 0], [4, 55, 3]],
three: [[1, 4, 6], [2, 0, 0], [3, 5, 6], [4, 0, 0]],
};
const filterArrays = (arsObj, maxVal) => {
return Object.fromEntries(Object.entries(arsObj).map(([k, v]) => {
return [k, v.filter((a) => a[0] <= maxVal)];
}));
}
const result = filterArrays(arrays, 3);
console.log(result);
I would like to get the max of each type of bill using the reduce method.
The function has to itirate and compare each item to the next in line, then if the names match(item[0]) it should compare their values (item[1]) and store the biggest value with that original name.
I want to use reduce for this but am struggling to understanding how exactly accumulator is being applied here. Any suggestions? :)
const tempCollected= [
["TWENTY", 20],
["TWENTY", 40],
["TWENTY", 60],
["TEN", 10],
["TEN", 20],
["FIVE", 5],
["FIVE", 10],
["FIVE", 15],
["ONE", 1],
["QUARTER", 0.25],
["QUARTER", 0.5],
["DIME", 0.1],
["DIME", 0.2],
["PENNY", 0.01],
["PENNY", 0.02],
["PENNY", 0.03]
]
/* Desired outcome using reduce
[
["TWENTY", 60],
["TEN", 20],
["FIVE", 15],
["ONE", 1],
["QUARTER", 0.5],
["DIME", 0.2],
["PENNY", 0.03]
]
*/
/*My try */
const attempt=tempCollected.reduce(
(a,b,i,arr)=>{
if(b[i+1][0]===b[0]){ //if next item has the same name as the current
return [...a,b[0],Math.max(b[1],b[i+1][1])] //return Math.max(...of those two) + the original name of the bill
}
return [...a,b]
},[]
)
The way the problem appears to be set up requires a somewhat convoluted solution, since on each iteration, you may have to remove the previous element in the accumulator, or you may have to just add an element.
const tempCollected= [
["TWENTY", 20],
["TWENTY", 40],
["TWENTY", 60],
["TEN", 10],
["TEN", 20],
["FIVE", 5],
["FIVE", 10],
["FIVE", 15],
["ONE", 1],
["QUARTER", 0.25],
["QUARTER", 0.5],
["DIME", 0.1],
["DIME", 0.2],
["PENNY", 0.01],
["PENNY", 0.02],
["PENNY", 0.03]
];
const result = tempCollected.reduce((a, subarr) => {
// if no items have been iterated over yet, or if the type is new,
// push unconditionally
if (
!a.length || (
a[a.length - 1][0] !== subarr[0]
)) {
a.push(subarr);
return a;
}
// otherwise, remove the final item and push the new item
// if the final item's value is greater
if (subarr[1] > a[a.length - 1][1]) {
a.pop();
a.push(subarr);
}
return a;
}, []);
console.log(result);
If the method of solution isn't required to be reducing into an array, it would be much easier to group by turning it into an object instead.
const tempCollected= [
["TWENTY", 20],
["TWENTY", 40],
["TWENTY", 60],
["TEN", 10],
["TEN", 20],
["FIVE", 5],
["FIVE", 10],
["FIVE", 15],
["ONE", 1],
["QUARTER", 0.25],
["QUARTER", 0.5],
["DIME", 0.1],
["DIME", 0.2],
["PENNY", 0.01],
["PENNY", 0.02],
["PENNY", 0.03]
];
const grouped = {};
for (const [type, num] of tempCollected) {
grouped[type] = Math.max((grouped[type] || 0), num);
}
const result = Object.entries(grouped);
console.log(result);
I don't think reduce is the way to go here (it could obviously be done because at the end you are still looping through the array, but it seems more like an abuse of the method). Don't be afraid to do things more verbose! Short code does not mean better code.
Take a look at the following snippet:
const data = [
['TWENTY', 20],
['TWENTY', 40],
['TWENTY', 60],
['TEN', 10],
['TEN', 20],
['FIVE', 5],
['FIVE', 10],
['FIVE', 15],
['ONE', 1],
['QUARTER', 0.25],
['QUARTER', 0.5],
['DIME', 0.1],
['DIME', 0.2],
['PENNY', 0.01],
['PENNY', 0.02],
['PENNY', 0.03]
];
const group = (input) => {
const output = new Map();
input.forEach((item) => {
const [key, value] = item;
output.set(key, Math.max(output.get(key) || -Infinity, value));
});
return Array.from(output.entries());
};
console.log(group(data));
Just for completion, this would be the reduce method 'abuse'. Essentially it is used to store the output object or map as the accumulated value and loop at the same time:
const data = [
['TWENTY', 20],
['TWENTY', 40],
['TWENTY', 60],
['TEN', 10],
['TEN', 20],
['FIVE', 5],
['FIVE', 10],
['FIVE', 15],
['ONE', 1],
['QUARTER', 0.25],
['QUARTER', 0.5],
['DIME', 0.1],
['DIME', 0.2],
['PENNY', 0.01],
['PENNY', 0.02],
['PENNY', 0.03]
];
const result = data.reduce((acc, item, index, input) => {
acc[item[0]] = Math.max(acc[item[0]] || -Infinity, item[1]);
if (index < input.length - 1) {
return acc;
} else {
return Object.entries(acc);
}
}, {});
console.log(result);
I initially thought you can use something like:
const max = tempCollected.reduce((max, current) => current[1] > max[1] ? current : max)
Then I realized you wanted all of them. What you're trying to do isn't possible with reduce (or it's not the way to do it).
Doing array.reduce on the array will only return ["TWENTY", 20] as the item on the iteration, it won't give you the entire group of items that you want to accumulate. You either have to manually do it or you have to restructure your array.
const items = {
twenty: 0,
ten: 0,
five: 0,
one: 0,
...
}
collected.forEach((item) => {
if (item[1] > items[item[0]]) {
items[item[0]] = item[1]
}
}
Or something like that depending on how you structure your data.
Can be a oneliner using Array.reduce to create an object and convert its result back to an Array with Object.entries. In the snippet the initial array is shuffled (unsorted), so an extra sort is added to sort the result descending on the result values. Note that using this reducer lambda the order of initial values has become irrelevant.
// shuffled the values a bit
const temp = [
["TWENTY", 60],
["FIVE", 5],
["PENNY", 0.03],
["TWENTY", 40],
["TEN", 10],
["QUARTER", 0.5],
["TEN", 20],
["FIVE", 10],
["ONE", 1],
["FIVE", 15],
["TWENTY", 20],
["QUARTER", 0.25],
["DIME", 0.1],
["PENNY", 0.01],
["DIME", 0.2],
["PENNY", 0.02], ];
const collectedMaxValues = Object.entries(
temp.reduce( (acc, [key, val]) =>
( {...acc, [key]: (acc[key] || 0) > val ? acc[key] : val } ), {} )
).sort( ([,val1], [,val2]) => val2 - val1);
console.log(JSON.stringify(collectedMaxValues));
Maybe not the most elegant way, but this method doesn't rely on external variables to store end result, it converts reducer (a) into nested array on first step and with each iteration checks if the reducer already contains same name, if it does, updates the maximum value, otherwise adds a new item:
const tempCollected = [
["TWENTY", 20],
["TWENTY", 40],
["TWENTY", 60],
["TEN", 10],
["TEN", 20],
["FIVE", 5],
["FIVE", 10],
["FIVE", 15],
["ONE", 1],
["QUARTER", 0.25],
["QUARTER", 0.5],
["DIME", 0.1],
["DIME", 0.2],
["PENNY", 0.01],
["PENNY", 0.02],
["PENNY", 0.03]
]
/* Desired outcome using reduce
[
["TWENTY", 60],
["TEN", 20],
["FIVE", 15],
["ONE", 1],
["QUARTER", 0.5],
["DIME", 0.2],
["PENNY", 0.03]
]
*/
const attempt = tempCollected.reduce((a, b, i) =>
{
if (i == 1)
a = [a];
for (i = 0; i < a.length; i++)
{
if (a[i][0] == b[0])
return a[i][1] = Math.max(a[i][1], b[1]), a;
}
return a.push(b), a;
});
console.log("attempt", attempt)
Problem description:
The idea is to insert into existing intervals new interval which doesn't merge with existing intervals but fills the missing gaps between intervals. (This is not the interval merging problem)
For example, inserting interval [0, 7] to intervals [[0, 1], [3, 5]] would result new intervals with gaps filled [[0, 1], [1, 3], [3, 5], [5, 7]].
Interval range is already sorted smallest to larger [[0, 1], [3, 5]].
My current solution is a bit "broken", I ended up using too many if checks to cover some special cases which makes everything more complex then needed. I am looking for better ways to simplify the condition part. In the bottom of the code there are test cases included, also cases where my solution fails.
The test cases where my algorithm is failing and producing wrong results:
assert.deepEqual( // Broken
insertIntervalSec([[1, 5], [7, 10]], [4, 12]),
[[1, 5], [5, 7], [7, 10], [10, 12]],
);
assert.deepEqual(insertIntervalSec([[1, 1]], [1, 3]), [[1, 3]]); // Broken
function isOverLapping(a, b) {
return Math.max(a[0], b[0]) <= Math.min(a[1], b[1]);
}
function insertIntervalSec(arr, interval) {
const result = [];
let i = 0;
const contains = (a, b) => {
return a[0] >= b[0] && a[1] <= b[1]
};
if (arr.length <= 0) {
result.push(interval);
return result;
}
if (arr.length === 1 && contains(interval, arr[0])) {
result.push(interval);
return result;
}
// Start point
if (interval[1] >= arr[0][0] && isOverLapping(interval, arr[0])) {
result.push([interval[0], arr[0][0]]);
} else if (interval[1] <= arr[0][0]) {
result.push([interval[0], Math.min(interval[1], arr[0][0])]);
}
while (i < arr.length) {
const current = arr[i];
result.push(arr[i]);
if (!contains(interval, arr[i]) && isOverLapping(arr[i], interval)) {
const next = arr[i + 1];
// Special handling for the last item
if (next !== undefined) {
if (interval[1] > current[1]) {
result.push([current[1], next[0]]);
}
} else {
if (interval[0] <= current[0] && interval[1] <= current[1]) {
// TODO: No action
} else if (interval[0] >= current[0] || interval[1] >= current[0]) {
result.push([current[1], interval[1]]);
}
}
}
i++;
}
// End point
const len = arr.length;
const last = arr[len - 1];
if (last[1] <= interval[0] && !isOverLapping(last, interval)) {
result.push(interval);
}
return result;
}
assert.deepEqual(
insertIntervalSec([[1, 5], [10, 15], [20, 25]], [12, 27]),
[[1, 5], [10, 15], [15, 20], [20, 25], [25, 27]]
);
assert.deepEqual(
insertIntervalSec([[1, 5], [10, 15], [20, 25]], [-3, 0]),
[[-3, 0], [1, 5], [10, 15], [20, 25]]
);
assert.deepEqual(
insertIntervalSec([[1, 5], [10, 15], [20, 25]], [-3, 3]),
[[-3, 1], [1, 5], [10, 15], [20, 25]]
);
assert.deepEqual(
insertIntervalSec([[0, 5], [10, 15], [20, 25]], [15, 15]),
[[0, 5], [10, 15], [20, 25]]
);
assert.deepEqual(
insertIntervalSec([[0, 5], [10, 15], [20, 25]], [20, 21]),
[[0, 5], [10, 15], [20, 25]]
);
assert.deepEqual(
insertIntervalSec([[0, 5], [10, 15], [20, 25]], [26, 27]),
[[0, 5], [10, 15], [20, 25], [26, 27]]
);
assert.deepEqual(
insertIntervalSec([[0, 5], [10, 15], [20, 25]], [25, 27]),
[[0, 5], [10, 15], [20, 25], [25, 27]]
);
assert.deepEqual(insertIntervalSec([], [25, 27]), [[25, 27]]);
assert.deepEqual(insertIntervalSec([[1, 1]], [1, 1]), [[1, 1]]);
assert.deepEqual( // Broken
insertIntervalSec([[1, 5], [7, 10]], [4, 12]),
[[1, 5], [5, 7], [7, 10], [10, 12]],
);
assert.deepEqual(insertIntervalSec([[1, 1]], [1, 3]), [[1, 3]]); // Broken
assert.deepEqual(
insertIntervalSec2([[5, 5]], [6, 6]),
[[5, 5], [6, 6]]
);
assert.deepEqual(
insertIntervalSec2([[1, 3]], [6, 6]),
[[1, 3], [6, 6]]
);
With the exception of the last test case (see comment on question), this passes all the tests. The basic idea is you just keep track of start variable that indicated where how much of the inserted range you have used. This allows you to narrow it down to three cases:
the inserted interval fits entirely before the the current item
the current item in the iteration fits completely before the inserted interval
the item in the iteration overlaps.
After iterating the items, you can check if the inserted range has anything left to insert:
function insertIntervalSec(arr, insert) {
let start = insert[0]
let res = []
for (i = 0; i < arr.length; i++) {
let a = arr[i]
// smaller item in range
if (a[0] <= start) {
res.push(a)
start = Math.max(a[1], start)
continue
}
// moved past inserted interval add rest of arr
if (start >= insert[1]) {
res.push(...arr.splice(i))
break
}
// fill in spaces
let end = Math.min(insert[1], a[0])
res.push([start, end], a)
start = a[1]
}
// clean up left over range
if (start < insert[1]) res.push([start, insert[1]])
return res
}
console.log(insertIntervalSec([ [1, 5],[10, 15],[20, 25]], [-2, 27]))
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am trying to change the heatmap series data using setData() when the dropdown value is changed. Please check my working jsfiddle
When clicking on the second option from the dropdown then heatmap should redraw() with new series data.
You have wrong data format in setData method, you have a few arrays - it should be one array , similar to data in series:
chart.series[0].setData([
[0, 0, 16],
[0, 1, 14],
[0, 2, 38],
[0, 3, 24],
[0, 4, 67],
[1, 0, 92],
[1, 1, 58],
[1, 2, 78],
[1, 3, 117],
[1, 4, 48],
[2, 0, 35],
[2, 1, 15],
[2, 2, 123],
[2, 3, 64],
[2, 4, 52],
[3, 0, 72],
[3, 1, 132],
[3, 2, 114],
[3, 3, 19],
[3, 4, 16],
[4, 0, 38],
[4, 1, 5],
[4, 2, 8],
[4, 3, 117],
[4, 4, 115],
[5, 0, 88],
[5, 1, 32],
[5, 2, 12],
[5, 3, 6],
[5, 4, 120],
[6, 0, 13],
[6, 1, 44],
[6, 2, 88],
[6, 3, 98],
[6, 4, 96],
[7, 0, 31],
[7, 1, 1],
[7, 2, 82],
[7, 3, 32],
[7, 4, 30],
[8, 0, 85],
[8, 1, 97],
[8, 2, 123],
[8, 3, 64],
[8, 4, 84],
[9, 0, 47],
[9, 1, 114],
[9, 2, 31],
[9, 3, 48],
[9, 4, 94]
], true, true, false);
Live demo: http://jsfiddle.net/BlackLabel/g3snLqwm/
API: https://api.highcharts.com/class-reference/Highcharts.Series#setData
Is there a better way to find values?
let arrData = [[1, 0], [74, 0], [75, 1], [76, 1], [79, 1], [80, 0], [81, 0], [82, 0], [83, 1], [84, 0], [85, 0], [86, 0]];
let isn = 75;
function searchCount(arr, isn) {
for(var i = 0; i < arr.length; i++){
if(arr[i][0] == isn){
return arr[i][1];
}
}
}
console.log(searchCount(arrData, isn));
You could use Array#find.
The find() method returns a value in the array, if an element in the array satisfies the provided testing function. Otherwise undefined is returned.
let arrData = [[1, 0], [74, 0], [75, 1], [76, 1], [79, 1], [80, 0], [81, 0], [82, 0], [83, 1], [84, 0], [85, 0], [86, 0]];
let isn = 75;
function searchCount(arr, isn) {
var el = arr.find(a => a[0] === isn);
return el && el[1];
}
console.log(searchCount(arrData, isn));
Or use Map
The Map object is a simple key/value map. Any value (both objects and primitive values) may be used as either a key or a value.
in combination with Map#get
The get() method returns a specified element from a Map object.
let arrData = [[1, 0], [74, 0], [75, 1], [76, 1], [79, 1], [80, 0], [81, 0], [82, 0], [83, 1], [84, 0], [85, 0], [86, 0]];
let isn = 75;
function searchCount(arr, isn) {
return (new Map(arr)).get(isn);
}
console.log(searchCount(arrData, isn));
You could also convert to a dictionary as below :
var dataMap =
arrData.reduce(function(p, c) { p[c[0]] = c[1]; return p; }, {});
You could use dataMap to search by passing the item to search as an index to dataMap:
dataMap[75]