I have to arrays which are related.
shortArray = ["ID-111", "ID-222"]
longArray = ["ID-111 bis", "ID-222 bis"]
I created them like that because I needed unique IDs in previous steps and now I must use the same color for each pair in the chart I'm drawing them.
My aim is to generate a string with this form:
{
"ID-111 bis" : chart.color("ID-111"),
"ID-222 bis" : chart.color("ID-222"),
...
}
I tried to do it like this:
const result = {}
for(const item of longArray) {
result[item]=[];
result[item].push({item : "chart.color(" + shortArray+ ")"});
}
Which gives me this wrong output:
{
"ID-111 bis" :[{item: "chart.color(ID-111,ID-222)"}],
"ID-222 bis" :[{item: "chart.color(ID-111,ID-222)"}]
}
Any ideas what should I change?
LATER EDIT:
I saw many answers which are pretty similar but there is a condition that must be respected:
The second argument should not be in quotes.
"ID-111 bis" : chart.color("ID-111") - good
"ID-111 bis" : "chart.color("ID-111")" - bad
You need to use the item's value instead of actualValue which seems to be some static value and is not dependent on item in your logic
And every array item seems to be a new array, which is not what you are looking for
result[item] = {item : "chart.color(" + item.split(" ")[0] + ")"};
Even more precisely
var finalValue = {};
shortArray.forEach( function(s){
finalValue[s+" bis"] = chart.color(s); //assuming that chart.color is the function you want to invoke
})
Why are you making an array and pushing an element inside ? If you want to get layout like:
{
"ID-111 bis" : chart.color("ID-111"),
"ID-222 bis" : chart.color("ID-222"),
...
}
simply remove the [] part.
const result = {}
for(const item of longArray) {
result[item] = { "item" : "chart.color(" + shortArray+ ")"});
}
If both arrays have the same length:
shortArray = ["ID-111", "ID-222"]
longArray = ["ID-111 bis", "ID-222 bis"]
result = {}
for (var i = 0; i < longArray.length; i++) {
result[ longArray[i] ] = "chart.color(" + shortArray[i] + ")";
}
https://jsfiddle.net/47qcrvqh/
You can use .reduce function of array
var shortArray = ["ID-111", "ID-222"]
var longArray = ["ID-111 bis", "ID-222 bis"]
var result = longArray.reduce((res,key,index)=>{
// Can call chart.color without quotes if that's requirement
res[key] = 'chart.color("'+shortArray[index]+'")';
return res;
},{})
console.log(result)
You should execute the chart.color(actualTitle) so it will return a value, Try :
const result = {}
for (var i = 0; i < longArray.length; i++)
{
result[longArray[i]] = 'chart.color("' + shortArray[i] + '")';
// result[longArray[i]] = chart.color(shortArray[i]);
}
Hope this helps.
shortArray = ["ID-111", "ID-222"]
longArray = ["ID-111 bis", "ID-222 bis"]
const result = {}
for (var i = 0; i < longArray.length; i++) {
result[longArray[i]] = 'chart.color("' + shortArray[i] + '")';
// result[longArray[i]] = chart.color(shortArray[i]);
}
console.log(result);
Related
Supposed I have a string of
let check = 'test_name=sdf&test_name=dfgdfg&test_last_name=dfg';
Is there a way in js where i can merge the duplicates and just append the value of it with comma
the output should be
test_name=sdf,dfgdfg&test_last_name=dfg;
any idea how can i do it
this is what i have tried so far
this is the simplfied version
test2: function() {
let test2 = ['val1','val2','val3'];
let test3 = ['opt1','opt1','opt3'];
let filter = '';
for (let i = 0; i < test2.length; i++) {
let text = test2[i]; // input value
let val =test3[i]; // option value
filter += val + '=' + text;
if (filter.includes(val) === true) {
filter += ',' + text;
}
i !== test2.length-1 ? filter += '&' : '';
}
console.log(filter);
},
the output is opt1=val1,val1&opt2=val2,val2&opt3=val3,val3
You can split the string first by & and then map through values and split them again using =, now using reduce and Map we club the values with same key name, and in the end join them to get the same structure as original string
let check = 'test_name=sdf&test_name=dfgdfg&test_last_name=dfg';
let final = check.split('&').map(v=>v.split('=')).reduce((r,[k,v])=>{
r.set(k, (r.get(k)||[]).concat(v))
return r
},new Map())
let output = [...final].map(v=>`${v[0]}=${v[1].join(',')}`).join('&')
console.log(output)
I have two arrays containing some parameter values. All elements in the arrays are strings like the following:
x = [ "vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=31,9400"]
y = ["nenndrehzahl=500,3000"]
Expected Output would be:
x = [ "vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=500,3000"]
I have tried using Array.Filter but can't seem to be able to filter only partially (like starting with the string instead of the whole string since that won't match as the values are different).
What I'd like is to be able to go through each element from array Y, and search if the element(string before "=") exists in array X and replace the value(s) of that element in array X.
for(var i=0;i<x.length;i++){
var currentStr = x[i];
var currentInterestedPart = /(.+)=(.+)/.exec(currentStr)[1];
var replacePart = /(.+)=(.+)/.exec(currentStr)[2];
for(var j=0;j<y.length;j++){
if(!y[j].startsWith(currentInterestedPart)) {continue;}
var innerReplacePart = /(.+)=(.+)/.exec(y[j])[2];
x[i] = currentStr.replace(replacePart,innerReplacePart);break;
}
}
Try this. This makes use of RegEx and it is less error prone.
You can use Map and map
First create a Map from array y, split each element by = use first part as key and second part as value
Loop over x array, split each element by = and use first part as key to search in Map if it's present use value from Map else return without any change
let x = ["vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=31,9400"]
let y = ["nenndrehzahl=500,3000"]
let maper = new Map(y.map(v => {
let [key, value] = v.split('=', 2)
return [key, value]
}))
let final = x.map(v => {
let [key, value] = v.split('=', 2)
if (maper.has(key)) {
return key + '=' + maper.get(key)
}
return v
})
console.log(final)
For each value in the y array, iterate and check if the word exist in the x array. Once you find a match just update the value. (The below solution mutates the original array)
const x = [ "vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=31,9400"],
y = ["nenndrehzahl=500,3000"],
result = y.forEach(word => {
let [str, number] = word.split('=');
x.forEach((wrd,i) => {
if(wrd.split('=')[0].includes(str)) {
x[i] = word;
}
});
});
console.log(x);
I'd suggest using combination of reduce + find - this would accumulate and give you the results you're expecting.
var x = [ "vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=31,9400"]
var y = ["nenndrehzahl=500,3000"]
var combinedArr = x.reduce((acc, elem, index) => {
const elemFoundInY = y.find((yElem) => yElem.split("=")[0] === elem.split("=")[0]);
if (elemFoundInY) {
acc = [...acc, ...[elemFoundInY]]
} else {
acc = [...acc, ...[elem]];
}
return acc;
}, [])
console.log(combinedArr);
You can use .startsWith() to check if element start with key= and then replace its value:
let x = [ "vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=31,9400"];
let y = ["nenndrehzahl=500,3000"];
y.forEach(val => {
let [key, value] = val.split("=");
for (let i = 0; i < x.length; i++) {
if (x[i].startsWith(`${key}=`)) x[i] = `${x[i].split("=")[0]}=${value}`;
}
})
console.log(x)
Try this:
y.forEach(item => {
const str = item.split("=")[0];
const index = x.findIndex(el => el.startsWith(str));
if (index) {
const split = x[index].split('=');
x[index] = `${split[0]}=${split[1]}`;
}
})
Here is my code :
var doc = app.activeDocument;
var allLayers = new Array;
var allLayers = collectAllLayers(doc, allLayers);
function collectAllLayers (doc, allLayers){
for (var m = 0; m < doc.layers.length; m++){
var theLayer = doc.layers[m];
if (theLayer.typename === "ArtLayer"){
allLayers.push(theLayer);
}else{
collectAllLayers(theLayer, allLayers);
}
}
return allLayers;
}
alert("array_layers : " + allLayers);
I am getting in alert array like this
[Layer1],[Layer2],[Layer3];
and I want make it looks like this :
[Layer1,Layer2,Layer3];
Thanks for answers and help in advance!
The code in question already works correctly. Referring to the documentation on ArtLayer, you can prove this by printing some of the properties for each of the objects in the array:
function collectAllLayers (layerSet, layers){
for (var i = 0; i < layerSet.layers.length; i++){
var layer = layerSet.layers[i];
if (layer.typename === "ArtLayer"){
layers.push(layer);
} else {
collectAllLayers(layer, layers);
}
}
return layers;
}
function printable (artLayers) {
var layerDescriptions = [];
for (var i = 0; i < artLayers.length; i++) {
var layer = artLayers[i];
layerDescriptions.push(
'{ name: ' + layer.name +
', kind: ' + layer.kind +
', opacity: ' + layer.opacity +
', visible: ' + layer.visible +
' }'
);
}
return layerDescriptions;
}
var artLayers = collectAllLayers(app.activeDocument, []);
var layerDescriptions = printable(artLayers);
alert(layerDescriptions);
Code in the question do display single level array of ArtLayer objects. One can be confused, because toString method of ArtLayer object returns name of the layer in square brackets (in version of PS that I have installed (v19.1.5), "ArtLayer" string is displayed before layer name, but still inside square brackets). For example:
var doc = app.activeDocument;
alert(doc.layers[0]); // Alerts "[ArtLayer Layer 1]"
To flatten array ary you can use [].concat.apply([], ary), like in:
var ary = [1, ["A", "B", "C"], 3];
alert(ary[2]); // Alerts "3"
alert([].concat.apply([],ary)[2]); // Alerts "B"
How about using the allLayers.push(theLayer[0]); instead of allLayers.push(theLayer);.
Have you tried to flat the list in the recursive result?
var doc = app.activeDocument;
var allLayers = new Array;
var allLayers = collectAllLayers(doc, allLayers);
function collectAllLayers (doc, allLayers){
for (var m = 0; m < doc.layers.length; m++){
var theLayer = doc.layers[m];
if (theLayer.typename === "ArtLayer"){
allLayers.push(theLayer);
}else{
flatten(collectAllLayers(theLayer, allLayers));
}
}
return flatten(allLayers);
}
function flatten(arr) {return arr.reduce(
(a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
)};
alert("array_layers : " + allLayers);
you can use
const flatten = (layers, allLayers) => layers.reduce((acc,layer) => (Array.isArray(layer)) ? collectAllLayers(layer, acc) : acc.push(layer), allLayers);
const collectAllLayers = (doc, allLayers) => flatten(doc.layers, allLayers);
This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 6 years ago.
I have a JavaScript array:
var j_array = new Array();
j_arry=["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10"];
I need to find how many times the class is coming and its array key, so I use:
found = $.inArray('class', j_array); ` But it returns `-1`;
Then I use:
var search = 'class';
$.each([j_array], function(index, value){
$.each(value, function(key, cell){
if (search.indexOf(cell) !== -1)
console.log('found in array '+index, cell);
});
});
But that is also wrong. How do I solve this?
From this array I want to get the following:
Class coming 4 times, at key 0, 2, 3, and 7
I want to make a separate array of class only, that is,
new_array = ["class:1", "class:2", "class:3", "class:10"];
Currently there are four classes in j_array. How can I get the Nth class value
That is, 1st class value ="class:1", 2nd class value="class:5", etc.
You could filter elements which match in a new array and just return the length of this new array
var j_arry = ["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10"];
var res = j_arry.filter(x => x.includes("class"));
var key = res.map(x => x.split(":")[1]);
console.log("Class coming " + res.length + " , at key " + key.join(","));
console.log("new array = ", res);
Use Array.prototype.filter to filter out the elements of the array that contains the string class - see demo below:
var j_array =["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10"];
var result = j_array.filter(function(e){
return e.indexOf('class')!==-1;
});
console.log(result);
EDIT:
To get the list of indexes too, you can try this:
var j_array =["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10"];
var filteredIndices = []
var filtered = j_array.filter(function(e,i){
if(e.indexOf('class')!==-1) {
filteredIndices.push(i);
return true;
} else {
return false;
}
});
console.log(filtered);
console.log(filteredIndices);
// Nth class value
console.log(filtered[2]); // this prints the 3rd one
.as-console-wrapper{top:0;max-height:100%!important;}
Here is the answer to your questions 1 + 2. It is also 'n' proof so answers your part 3 also. This works by old-fashioned hard graft rather than funky functions. The original array entries are split and filtered then if qualifying we store in an associative array (results) using a pointer array (list) to make it easier to give a sorted result and pull the values from the associative array. The max variable is probably not necessary but included for clarity - could have used list.length instead. Note that the list[] array will be sparse (missing steps) so we test each entry before use in the output steps.
var j_array = new Array();
j_arry=["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10","class:1"];
var a, result = [], list=[], max = -1
for (var i =0; i < j_arry.length; i = i + 1) {
var a = j_arry[i].split(":")
if ( a[0] === "class") {
var key = "c" + a[1]
if ( !result[key] ) { result[key] = {pos:[]}}
result[key].cnt = result[key].cnt ? result[key].cnt + 1 : 1;
result[key].pos.push(i)
list[parseInt(a[1])] = "c" + a[1]
max = parseInt(a[1]) > max ? a[1] : max;
}
}
// say locations
for (var i = 0; i < max; i = i + 1) {
if (list[i]) {
key = "c" + i
console.log("Class " + i + " occurs at " + result[key].pos.toString() )
}
}
// make new array
var newArray=[]
for (var i = 0; i < max; i = i + 1) {
if (list[i]) {
newArray.push("Class:" + i)
}
}
console.log("New array=" + newArray.toString() )
Results are:
Class 1 occurs at 0,8
Class 3 occurs at 3
Class 5 occurs at 2
New array=Class:1,Class:3,Class:5
Single reduce is sufficient here.
var arr = ["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10"],
res = arr.reduce((p,c) => c.includes("class") ? (p.count++, p.keys.push(c.split(":")[1]), p)
: p ,{count:0, keys:[]});
console.log(res);
You can use the filter and map functions to filter your array to have only elements that match the text 'class', and use array index notation to access the nth element in the array. Check the below code snippet I hope it will be of help to you.
The below code snippet uses ES6 arrow syntax.
var arr = ["class:1", "division:a", "class:5", "class:3", "division:b", "division:c", "division:d", "class:10"];
var result = arr.filter(x => x.indexOf('class') !== -1);
var indices = result.map(x => arr.indexOf(x));
console.log(indices);
console.log(result);
var nValue = window.prompt('Enter n value');
console.log(result[nValue]);
If you're using jQuery to support some really old browser that still don't implement the new Array functions, and you don't want to polyfill those because you're already using jQuery, then you can use the jQuery equivalents:
var arr = ["class:1", "division:a", "class:5", "class:3", "division:b", "division:c", "division:d", "class:10"]
var result = $.grep(arr, function (x) { return x.indexOf('class') !== -1 })
var indices = $.map(result, function (x) { return arr.indexOf(x) })
This is the same code as this answer, but using jQuery.
You have to do map first then filter.
var j_array = ["class:1", "division:a", "class:5", "class:3", "division:b", "division:c", "division:d", "class:10"];
var result = j_array.map(function(e, i) {
return e.indexOf('class') > -1 ? '' + i : false;
}).filter(function(e) {
return !!e;
});
console.log(result);
let the array be
var array=
[
"me=Salman","Profession=student","class=highschool"
]
How do I extract the value of 'me' here?
Try this:
var result = '';
for(var values in array){
if(values.indexOf('me=') !== -1 ){
result = values.split('=')[1];
break;
}
}
You will need to search the array for your desired portion of the string, then remove what you searched for from the indicated string.
var array = [ "me=Salman" , "Profession=student" , "class=highschool" ];
var findMatch = "me=";
var foundString = "Did not find a match for '"+findMatch+"'.";
var i = 0;
for (i = 0; i<array.length; i++) //search the array
{
if(array[i].indexOf(findMatch) != -1) // if a match is found
{
foundString = array[i]; //set current index to foundString
foundString = foundString.substring(findMatch.length, array[i].length); //remove 'me=' from found string
}
}
Try this:
var a = [ "me=Salman" , "Profession=student" , "class=highschool" ];
var result = a.filter(function(e){return /me=/.test(e);})[0]; // Find element in array
result = result.length ? result.split('=').pop() : null; // Get value
Or function:
var array = [ "me=Salman" , "Profession=student" , "class=highschool" ];
function getVal(arr, key){
var reg = new RegExp(key + '=');
var result = arr.filter(function(e){ return reg.test(e)})[0];
return result.length ? result.split('=').pop() : null;
}
console.log( getMe(array, 'me') );