How to create new array with key and value with 2 arrays? - javascript

I have 2 array, one for key and other for value.
Want create new array with these arrays.
key: [01, 02, 03]
value: ["hi", "hello", "welcome"]
Output I need:
[
{"key": "1","value":"hi"},
{"key": "2","value":"hello"},
{"key": "3","value":"welcome"}
]
How to get result by this way.?
My code:
output = key.map(function(obj, index){
var myObj = {};
myObj[value[index]] = obj;
return myObj;
})
Result:
[
{"1","hi"},
{"2","hello"},
{"3","welcome"}
]

const keys = [01, 02, 03];
const values = ['hi', 'hello', 'welcome'];
const res = keys.map((key, ind) => ({ 'key': ''+key, 'value': values[ind]}));
console.log(res);
There is also a proposal for the following method of Object, fromEntries, which will do exactly what you want to, but it is not supported yet by the major browsers:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries

var myArray = [];
var keys = [45, 4, 9];
var cars = ["Saab", "Volvo", "BMW"];
cars.forEach(myFunction);
var txt=JSON.stringify(myArray);
document.getElementById("demo").innerHTML = txt;
function myFunction(value,index,array) {
var obj={ key : keys[index], value : value };
myArray.push(obj);
}
<p id="demo"></p>

You could take an object with arbitrary count of properties amd map new objects.
var key = [1, 2, 3],
value = ["hi", "hello", "welcome"],
result = Object
.entries({ key, value })
.reduce((r, [k, values]) => values.map((v, i) => Object.assign(
{},
r[i],
{ [k]: v }
)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Here you have another apporach using reduce():
let keys = [01, 02, 03];
let values = ['hi', 'hello', 'welcome'];
let newArray = keys.reduce((res, curr, idx) => {
res.push({'key': curr.toString(), 'value': values[idx]});
return res;
}, []);
console.log(newArray);

Related

javascript filter multidimensional array

I am not familiar with javascript but I need to use it for a callback with Bokeh. I created a multidimensional array with the following content (pseduo code)
items =[
["id", Array(2898)],
["NAME", Array(2898)],
["ADDRESS", Array(2898)],
["PHONE", Array(2898)],
];
I would like to create a new array containing a subset filtered by an array of "ids"
I tried using filter and some but can't seem to get it work. here is what I got so far
let items = Object.keys(items_obj).map((key) => [key, items_obj[key]]);
let filter_items = items.filter(function(item){
return item.some(e => e['id'] === ids[0]);
Is there a simplye whay to do this? In python, I would simply filter df[df['ids'].isin([3, 6])]
Many thanks
If you want to extract a "column" of data from a matrix, you can find the column index by find the value index within the corresponding key array.
const data = [
["id", [1, 2, 3]],
["NAME", ['Bob', 'Joe', 'Nancy']],
["ADDRESS", [1, 2, 3]],
["PHONE", [1, 2, 3]]
];
const
itemsObj = Object.fromEntries(data), // Matrix to Object
itemsArr = Object.entries(itemsObj); // Object to Matrix
const getFrame = (dataFrames, key, value) => {
const [ , keyValues ] = dataFrames.find(([key]) => key === key);
const index = keyValues.indexOf(value);
return dataFrames.map(([k, v]) => [ k, v.find((w, i) => i === index) ]);
};
const
frame = getFrame(data, 'id', 2),
frameObj = Object.fromEntries(frame);
console.log(frameObj);
.as-console-wrapper { top: 0; max-height: 100% !important; }
If you want to select a range of "frames", you can modify the program as seen below:
const data = [
["id", [1, 2, 3]],
["NAME", ['Bob', 'Joe', 'Nancy']],
["ADDRESS", [1, 2, 3]],
["PHONE", [1, 2, 3]]
];
const getFrames = (dataFrames, key, values) => {
const [ , keyValues ] = dataFrames.find(([key]) => key === key);
const indicies = values.map(val => keyValues.indexOf(val)).filter(i => i > -1);
return indicies.map(index =>
dataFrames.map(([k, v]) =>
[k, v.find((x, i) => i === index)]));
};
const
frames = getFrames(data, 'id', [2, 3]),
frameObjs = frames.map(frame => Object.fromEntries(frame));
console.log(frameObjs);
.as-console-wrapper { top: 0; max-height: 100% !important; }

Transform 2D array to object and use first array element as key

Imagine I have this array of arrays:
myData = [
["wantThisAsKey1",someElement1,anotherElement1],
["wantThisAsKey2",someElement2,anotherElement2]
]
I need to convert this array to an object where the first element of each array is used as the key:
myDataObject = {
"wantThisAsKey1": [someElement1,anotherElement1],
"wantThisAsKey2": [someElement2,anotherElement2],
}
How can I do this in a general way, something like myDataObject = convertToObject(myData) ?
Try this:
let myData = [
["wantThisAsKey1","someElement1","anotherElement1"],
["wantThisAsKey2","someElement2","anotherElement2"]
];
let myDataObject = convertToObject(myData);
console.log(myDataObject);
function convertToObject(data){
let res = {};
for(let i = 0; i < data.length; i++)
res[data[i][0]] = data[i].slice(1);
return res;
}
To achieve this you can combine the arrays reduce function with destructuring assignment:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
myData = [
["wantThisAsKey1", 1, 2],
["wantThisAsKey2", 2, 3]
]
const newobject = myData.reduce((acc, elem) => {
const [key, ...rest] = elem;
acc[key] = rest
return acc;
}, {})
console.log(newobject);
// Result: { wantThisAsKey1: [ 1, 2 ], wantThisAsKey2: [ 2, 3 ] }
try using reduce here. like this.
const result = myData.reduce( (result, ele) => {
const [key, ...other] = ele
result[key] = other
return result
}, {})
// output = { wantThisAsKey1: [ 'someElement1', 'anotherElement1' ], wantThisAsKey2: [ 'someElement2', 'anotherElement2' ] }

convert array into given type of array of object

I have an array of type:-
const arr = ['abc','def','ghi'];
but I want this array in the form of
const arr2 = [
{value: 'abc'},
{value: 'def'},
{value: 'ghi'},
];
I am not getting the idea to do it.
use a map function to generate a new array with the type you want
for your reference, Array.prototype.map()
const arr=['abc','def','ghi'];
const arr2 = arr.map(item => ({value: item}));
console.log(arr2);
You can try using Array.prototype.map():
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
var arr = ['abc','def','ghi'];
arr = arr.map(value => ({value}));
console.log(arr);
You can use map to transform each item of an array to another value.
const arr = ['abc', 'def', 'ghi'];
const arr2 = arr.map(value => ({ value: value })
// const arr2 = [
// { value: "abc" },
// { value: "def" },
// { value: "ghi" }
// ];
If you want to be clever you can simplify this to
const arr2 = arr.map(value => ({ value })
See Array.prototype.map
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
More elegant way that I prefer:
Array.from(arr, (v) => {return {value: v};})

Javascript how to join two arrays having same property value?

How do I join arrays with the same property value? I cannot map it because it has different indexes.
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
expected output:
var array3 = [
{'label':"label1",'value':"TEXT",'position':0},
{'label':"label2",'value':"SELECT", 'position':1}
];
This is what I did, I cannot make it work,
var arr3 = arr1.map(function(v, i) {
return {
"label": v.label,
"position": v.position,
"value": arr2[?].value
}
});
I think you can use array#reduce to do something like this perhaps:
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
var array3 = array2.reduce((arr, e) => {
arr.push(Object.assign({}, e, array1.find(a => a.label == e.label)))
return arr;
}, [])
console.log(array3);
You could take a Map and check the existence for a new object.
var array1 = [{ label: "label1", position: 0 }, { label: "label3", position: 2 }, { label: "label2", position: 1 }],
array2 = [{ label: "label1", value: "TEXT" }, { label: "label2", value: "SELECT" }],
map = array1.reduce((m, o) => m.set(o.label, o), new Map),
array3 = array2.reduce((r, o) => {
if (map.has(o.label)) {
r.push(Object.assign({}, o, map.get(o.label)));
}
return r;
}, []);
console.log(array3);
.as-console-wrapper { max-height: 100% !important; top: 0; }
As per the effort, we take an assumption that array1 will be having all the labels that are in array2.
Based on that first, create a map for array2and with key being labels. Post that, filter out array1 items which have labels existing in the map and then finally merging the objects of the filtered array and its corresponding values in map extracted from array2.
var array1 = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}];
var array2 = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}];
let map = array2.reduce((a,{label, ...rest}) => Object.assign(a,{[label]:rest}),{});
let result = array1.filter(({label}) => map[label]).map(o => ({...o, ...map[o.label]}));
console.log(result);
Also, in the above snippet, you can improve the performance further by using Array.reduce against filter and map functions to retrieve the result.
var array1 = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}];
var array2 = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}];
let map = array2.reduce((a,{label, ...rest}) => Object.assign(a,{[label]:rest}),{});
let result = array1.reduce((a,o) => {
if(map[o.label]) a.push({...o, ...map[o.label]});
return a;
}, []);
console.log(result);
If you don't know in advance which array(s) will have their labels be a subset of the other (if any), here's a method that allows for either array1 or array2 to have labels that the other array lacks. Use reduce over array1, finding the matching label in array2 if it exists:
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
const output = array1.reduce((a, { label, position }) => {
const foundValueObj = array2.find(({ label: findLabel }) => findLabel === label);
if (!foundValueObj) return a;
const { value } = foundValueObj;
a.push({ label, value, position });
return a;
}, []);
console.log(output);
See Array.prototype.map() and Map for more info.
// Input.
const A = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}]
const B = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}]
// Merge Union.
const mergeUnion = (A, B) => {
const mapA = new Map(A.map(x => [x.label, x]))
return B.map(y => ({...mapA.get(y.label), ...y}))
}
// Output + Proof.
const output = mergeUnion(A, B)
console.log(output)
This works.
Approach: Concatenate the objects with same label, using Object.assign()
var array1 = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}];
var array2 = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}];
var result = [];
array2.forEach(function(value, index){
result.push(Object.assign({},array1.find(function(v,i){return v.label==value.label}),value));
});
console.log(result)
Im not good with javascript,but you could also do this
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
var array3=[];
for(var i=0;i<array1.length;i++)
{
for(var x=0;x<array2.length;x++)
{
console.log(array1[i]['label'] == array2[x]['label']);
if(array1[i]['label'] == array2[x]['label']){
array3.push({label:array1[i]['label'],value:array2[x]['value'],position:array1[i]['position']});
}
}
}
console.log(array3);

UnderscoreJs: flatten array of objects

There is an array of objects
[
{a:1,val:[11,12]},
{a:9,val:[21,22]},
{a:7,val:[31,32]},
{a:8,val:[41,42]}
]
I am trying to convert it into:
[ [{a:1,val:11},{a:9,val:21},{a:7,val:31},{a:8,val:41}] ,
[{a:1,val:12},{a:9,val:22},{a:7,val:32},{a:8,val:42}]
]
How can I use underscore.js chain/map/pluck etc... function to get the flatten result in specified format in the cleanest way?
You could use Array#forEach and build the nested parts upon.
var data = [{ a: 1, val: [11, 12] }, { a: 9, val: [21, 22] }, { a: 7, val: [31, 32] }, { a: 8, val: [41, 42] }],
result = [];
data.forEach(function (a, i) {
a.val.forEach(function (b, j) {
result[j] = result[j] || [];
result[j][i] = { a: a.a, val: b };
});
});
console.log(result);
You can use array's reduce like this
var data = [
{a:1,val:[11,12]},
{a:9,val:[21,22]},
{a:7,val:[31,32]},
{a:8,val:[41,42]}
]
var result = data.reduce((res, next) => {
res[0].push({a: next.a, val: next.val[0]});
res[1].push({a: next.a, val: next.val[1]});
return res;
}, [[], []])
console.dir(result)
I have done as you have requested but used plain ES6 instead of underscore.
var restructure = (x)=>
[x.map(({a,val})=>({a,val:val[0]})),x.map(({a,val})=>({a,val:val[1]}))]
var result = restructure([
{a:1,val:[11,12]},
{a:9,val:[21,22]},
{a:7,val:[31,32]},
{a:8,val:[41,42]}
])
//[[{"a":1,"val":11},{"a":9,"val":21},{"a":7,"val":31},{"a":8,"val":41}],[{"a":1,"val":12},{"a":9,"val":22},{"a":7,"val":32},{"a":8,"val":42}]]
Here's a solution using underscore:
var result = _.chain(data)
.map(item => _.map(item.val, val => ({a: item.a, val})))
.unzip()
.value();
var data = [
{a:1,val:[11,12]},
{a:9,val:[21,22]},
{a:7,val:[31,32]},
{a:8,val:[41,42]}
]
var result = _.chain(data)
.map( item => _.map(item.val, val => ({a: item.a, val})))
.unzip()
.value();
document.getElementById('result').textContent = JSON.stringify(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.2/underscore.js"></script>
<p>
<pre id="result"></pre>
</p>

Categories