I have an array of elements containing iPhone models and 4 values that come after it, like this:
const arr = ['ip6s+', '35', '15', '10', '10', 'ip7', '40', '20', '15', '15']
I want to turn this into an object that looks like this:
const Obj = {
'ip6s+': ['35', '15', '10', '10'],
'ip7+' : ['90', '60', '35', '30']
}
Where the first object is the phone model and every fourth is its values. How to do that?
You can use slice:
const arr = ['ip6s+', '35', '15', '10', '10','ip7', '40', '20', '15','15'];
const obj = {};
const n = 4; // the number of values after the model name
for (var i = 0; i < arr.length; i += n + 1) {
obj[arr[i]] = arr.slice(i + 1, i + n + 1);
}
console.log(obj);
You could also use reduce()
const arr = ['ip6s+', '35', '15', '10', '10','ip7', '40', '20', '15','15']
let lastCurr = null;
const result = arr.reduce( ( res, curr, ix ) => {
if( 0 == ix % 5 ){
res[ curr ] = [];
lastCurr = curr;
}else
res[ lastCurr ].push( curr );
return res;
}, {} )
If your keys are always supposed to be isNaN and first value always corresponds to key, than you can do something like this, this will be more dynamic in case there are dynamic number of elements between two keys
const arr = ['ip6s+', '35', '15', '10', '10', 'ip7', '40', '20', '15', '15']
let getDesiredFormat = (arr) => {
let currentKey = arr[0]
let final = arr.reduce((op, inp) => {
if (isNaN(inp)) {
op[inp] = []
currentKey = inp
} else {
op[currentKey].push(inp)
}
return op
}, {})
return final
}
console.log(getDesiredFormat(arr))
If the array starts with an item that starts with "ip" and starting with that is the trigger for a new key in the object, you could use startswith.
This allows a variable number of items after ip.
const arr = ['ip6s+', '35', '15', '10', '10', 'ip7', '40', '20', '15', '15'];
const obj = {};
let currKey = arr.slice(0, 1);
arr.forEach(s => s.startsWith("ip") ? (currKey = s, obj[s] = []) : obj[currKey].push(s));
console.log(obj);
Use slice method, also the following example should work no matter how many elements in the array :
this should work also if there are elements before 'ip6s+' BUT the 'ip6s+' must always precede 'ip7'.
const arr = ['some', 'elemnts', 'in', 'front', 'ip6s+', '35', '15', 'abc', '80', '58', '10', '10', 'ip7', '40', '20', '15', '15', '100', 'xyz'],
l = arr.length,
ip6sIndex = arr.indexOf('ip6s+'),
ip7Index = arr.indexOf('ip7'),
obj = {};
obj[arr[ip6sIndex]] = arr.slice(ip6sIndex + 1, ip7Index); /** get the items after 'ip6s+' **/
obj[arr[ip7Index]] = arr.slice(-(l - ip7Index) + 1); /** get the items after 'ip7' **/
console.log(obj);
Related
I have an array and i want to get the values < 20, i'm having the new array with that values but is returning undefined values that are the numbers that doesn't qualify that condition.
let dataJobs = ['13', '12', '13', '52', '56'];
var valuesUnderT = dataJobs.map((element, index) => {
if (dataJobs[index] < 20) {
return element;
}
});
The array that is being returned is:
[ '13', '12', '13', undefined, undefined ]
Why not take Array#filter?
Array#map returns for each element of the array a value.
let dataJobs = ['13', '12', '13', '52', '56'],
valuesUnderT = dataJobs.filter(v => v < 20)
console.log(valuesUnderT);
I have two arrays
let arr1 = [{'id': 'ee', 'seat': '12'},
{'id': 'aa', 'seat': '8'}
]
let arr2 = [
{'id': 's22', 'num': ''},
{'id': '2s2', 'num': ''}
]
I want to copy seat values from arr1 to num property at arr2, but I only get last arr1 seat value in for loop.
for( let i = 0; i <= arr1.length; i++) {
for( let x = 0; x <= arr2.length; x++) {
arr2[x]['num'] = arr1[i]['seat'];
}
}
console.log(arr2);
Iterate arr2 with Array.forEach(), and take the respective seat value by index from arr1:
const arr1 = [{'id': 'ee', 'seat': '12'},{'id': 'aa', 'seat': '8'}]
const arr2 = [{'id': 's22', 'num': ''},{'id': '2s2', 'num': ''}]
arr2.forEach((o, i) => o.num = arr1[i].seat)
console.log(arr2)
You need just a single loop and check if the index of the array if is (only) smaller than the length of the minimum of both arrays.
If the index get the length of an array, the access returns undefined, because this element is not in the array.
A further access to a property of this throws an error:
Unable to get property 'seat' of undefined or null reference
var arr1 = [{ id: 'ee', seat: '12' }, { id: 'aa', seat: '8' }],
arr2 = [{ id: 's22', num: '' }, { id: '2s2', num: '' }],
i, l;
for (i = 0, l = Math.min(arr1.length, arr2.length); i < l; i++) {
arr2[i].num = arr1[i].seat;
}
console.log(arr2);
You can do it in just one for loop.
for(let i = 0; i < arr1.length; i++) {
arr2[i].num = arr1[i].seat;
}
Hope this helps!
Assuming you want to match indices, this should do it.
const arr1 = [
{'id': 'ee', 'seat': '12'},
{'id': 'aa', 'seat': '8'}
]
const arr2 = [
{'id': 's22', 'num': ''},
{'id': '2s2', 'num': ''}
]
const result = arr2.map((e, i) => ({...e, ...{num: arr1[i].seat}}))
console.log(result)
If you want all of the seats in each num, it wouldn't be much harder.
I have 4 arrays of the following format
arr1 = ['Hello', 'World', 'Hi']
arr2 = ['1', '2', '3']
arr3 = ['foo', 'bar', 'foobar']
arr4 = ['10', '20', '30']
I am trying to add each value at index[i] to a new object, the object looks like this
obj = {
title: '',
score: '',
description: '',
value: '',
}
For each indexed value in the array I would like to push it to a new instance of the obj object so I can end up with this
objects = [
{
title: 'Hello',
score: '1',
description: 'foo',
value: '10',
},
{
title: 'World',
score: '2',
description: 'bar',
value: '20',
},
{
title: 'Hi',
score: '3',
description: 'foobar',
value: '30',
}
]
So far I have been trying something like
objects = []
arr1.forEach((key, i) => objects[key] = arr2[i])
But that is assigning them as arr1val : arr2val
I will ultimately be setting this to state in my react app and passing it to another component as props to render on the page. The data is coming in from 3 different APIs, I am doing this to try and standardise the data received from each API so my component can use the data to render an articles list and user can switch between feeds.
Map by the index of element across all arrays, also use map not forEach:
const objects = arr1.map((element, index) => (
{title: element, score: arr2[index], description: arr3[index], value: arr4[index]}
))
Live demo is below:
const arr1 = ['Hello', 'World', 'Hi']
const arr2 = ['1', '2', '3']
const arr3 = ['foo', 'bar', 'foobar']
const arr4 = ['10', '20', '30']
const objects = arr1.map((element, index) => (
{title: element, score: arr2[index], description: arr3[index], value: arr4[index]}
))
console.log(objects)
This code also works:
var arr = [];
for(var i=0; i<arr1.length; i++) {
arr[i] = {};
arr[i].title = arr1[i];
arr[i].score = arr2[i];
arr[i].description = arr3[i];
arr[i].value = arr4[i];
}
I suggest to use an array of arrays and another array for the keys. This allows an arbitrary count of arrays and keys to use for transforming the data into an array of objects with hte wanted properties.
var array1 = ['Hello', 'World', 'Hi'],
array2 = ['1', '2', '3'],
array3 = ['foo', 'bar', 'foobar'],
array4 = ['10', '20', '30'],
keys = ['title', 'score', 'description', 'value'],
result = [array1, array2, array3, array4].reduce(function (r, a, i) {
a.forEach(function (v, j) {
r[j] = r[j] || {};
r[j][keys[i]] = v;
});
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you don't want to type the property names twice,
you could do like this:
const descriptor = {
title: arr1,
score: arr2,
description: arr3,
value: arr4
};
const objects = arr1.map((tmp, i) => {
var o = {};
Object.keys(descriptor).forEach(name => o[name] = descriptor[name][i]);
return o;
});
A reducer method would be in place I suppose
const arr1 = ['Hello', 'World', 'Hi', 'Hello2', 'World2', 'Hi2'];
const arr2 = ['1', '2', '3', '11', '22', '33'];
const arr3 = ['foo', 'bar', 'foobar', 'sea', 'shell', 'sea weed'];
const arr4 = ['10', '20', '30', '100', '200', '300'];
const arrays2Objects = arr1.reduce( (obj, next, i) =>
obj.concat({title: next, score: arr2[i], description: arr3[i], value: arr4[i]}),
[]
);
console.log(arrays2Objects);
I have these two arrays:
var Names = ['jack', 'peter', 'jack', 'john'];
var Ids = ['1' , '2' , '3' , '4' ];
Also I have this variable:
var name = 'ja'; // to search in the Names array
I search name variable in the Names array as follow:
var MatchesNames = Names.filter(function(x){
if(x.indexOf(name) >= 0) return x
}).slice(0,4); // slice() makes limit the results
The output of above code is:
alert(MatchesNames);
//=> jack,jack
As you see there is two duplicate names (which have different ids) .. Now I need to pull their ids out from Ids array. How can I do that? I guess I need an object but really I don't know how can I use an object in this case.
I want this output:
//=> jack(1),jack(3)
How can I do that?
You can use the Array index as id, and process it like:
var names = ['jack', 'peter', 'jack', 'john'];
var ids = ['1' , '2' , '3' , '4' ];
var name = 'ja';
var result = [];
var zippedArray = names.map(function (e, i) {
return [names[i], ids[i]];
});
zippedArray.map(function(element, index) {
if(element[0].indexOf(name) >= 0) {
result.push( element[0] + "(" + element[1] + ")" );
}
});
console.log(result.toString());
// jack(1), jack(3)
If you want to associate the name with the id, you should really use an object; otherwise you will have to assume that the id array and names are in the correct order, but it would be difficult to guarantee.
var people = [
{ name: 'jack', id: 1 },
{ name: 'peter', id: 2 },
{ name: 'jack', id: 3 },
{ name: 'john', id: 4 }
];
var name = 'ja';
var matchedPeople = people.filter((person) => person.name.includes(name));
var matchedIds = matchedPeople.map((person) => person.id);
You could also incorporate Ramda/Lodash to compose these functions
Approach with an Array#forEach() and a result array with objects.
function find(o, s) {
var r = [];
o.names.forEach(function (a, i) {
if (~a.indexOf(s)) {
r.push({ id: o.ids[i], name: a });
}
});
return r;
}
var Names = ['jack', 'peter', 'jack', 'john'],
Ids = ['1', '2', '3', '4'],
result = find({ ids: Ids, names: Names }, 'ja');
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
document.write(result.map(function (a) { return a.name + '(' + a.id + ')'; }).join(','));
Check the documentation for .filter, there's an option to call with the array index.
(It also returns true/false, not the actual value, so current usage is wrong, but a side issue).
This way, you can get an array of the IDs that match, at the time they match:
var Names = ['jack', 'peter', 'jack', 'john'];
var Ids = ['1' , '2' , '3' , '4' ];
var name = 'ja';
var MatchesIds = [];
var MatchesNames = Names.filter(function(x, i){
console.log("Check: " + i + " : " + x)
if(x.indexOf(name) >= 0) {
MatchesIds.push(i)
return true
}
})
console.log(MatchesNames)
console.log(MatchesIds)
Example fiddle: https://jsfiddle.net/nkuntaup/
I'd use reduce:
var Names = ['jack', 'peter', 'jack', 'john'];
var Ids = ['1', '2', '3', '4'];
var search = name => Names.reduce((r, n, i) =>
n.indexOf(name) > -1 ? (r.push([n, Ids[i]]), r) : r, []);
results.innerHTML = JSON.stringify(search('ja'));
<pre id="results"></pre>
You may want something like this.
var Names = [{name: 'jack', id: 1}, {name: 'peter', id: 2}, {name: 'jack', id: 3}, {name: 'john', id: 4}];
var chars = 'ja';
var MatchesNames = Names.filter(function(x) {
if(x.name.indexOf(chars) >= 0) {
return x;
};
}).slice(0,4);
MatchesNames.forEach(function(person) {
console.log(person.name + '(' + person.id + ')');
});
I am not a professional but this may help. By the way you'll have to make some retouches.
var Names = ['jack', 'peter', 'jack', 'john'];
var Ids = ['1' , '2' , '3' , '4' ];
function fakeZip(arr1, arr2) {
var ret = new Object;
for (var i=0; i<arr1.length; i++) {
ret[arr2[i]] = arr1[i];
}
return ret;
}
var newobj = fakeZip(Names, Ids);
JSON.stringify(newobj);
/*
{"1":"jack","2":"peter","3":"jack","4":"john"}
*/
function lookFor(el, obj) {
res = []
for(key in obj) {
if(obj[key]== el ){
res.push(key)
}
}
return [el, res];
}
lookFor("jack", newobj)
/*
jack,1,3
*/
I have an object that contains a key and an array with some values inside of it.
var obj1 = {
'key': '1',
'values': ['a', 'b', 'c']
}
var obj2 = {
'key': '10',
'values': ['a', 'b']
}
I want to split this in other objects for each value in my values array to result something like this:
obj1 = 'key': '1', 'value':'a', 'index': '0';
obj2 = 'key': '1', 'value':'b', 'index': '1';
obj3 = 'key': '1', 'value':'c', 'index': '2';
obj4 = 'key': '10', 'value': 'a', 'index': '0';
obj5 = 'key': '10', 'value': 'b', 'index': '1';
Any ideas to do this?
Try this example
var brief = function(obj) {
var tmp = [],
i = 0,
l = obj.values.length;
while (i < l)
tmp.push({
key: obj.key,
index: i,
value: obj.values[i++]
});
return tmp;
};
var obj1 = brief({
key: '1',
values: ['a', 'b', 'c']
});
var obj2 = brief({
key: '2',
values: ['a', 'c']
});
document.write("<pre>");
document.write(JSON.stringify(obj1));
document.write("<br/>");
document.write(JSON.stringify(obj2));
document.write("</pre>");
Friend, it would be something like:
tmp = [];
obj1.values.forEach(function (e, i) {
tmp.push({key: obj1.key, value: e, index: i})
});
console.log(tmp);
assuming that you want
obj1 =[ { key: '1', value:'a', index: '0' },
{ key: '1', value:'b', index: '1'},
{ key: '1', value:'c', index: '2' }]
try
function splitArray( obj )
{
var output = [];
var keyValue = obj.key;
var values = obj.values;
for ( var counter = 0; counter < values.length; counter++ )
{
output.push( {
key : keyValue,
value : values[ counter ],
index : counter
} );
}
return output;
}
console.log( splitArray( obj1 ) );
function getTransformedObjects(obj) {
var ans = [];
if (obj.values) {
obj.values.forEach(function(value, index) {
var temp = {
'key': obj.key,
'value': value,
'index': index
};
ans.push(temp);
})
}
return ans;
}
//for display purpose
// usage
var obj1 = {
key: '1',
values: ['a', 'b', 'c']
}
console.log(getTransformedObjects(obj1));
$('.old').html(JSON.stringify(obj1))
$('.new').html(JSON.stringify(getTransformedObjects(obj1)));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div>old object</div>
<div class='old'></div>
<div>Trasnformed object</div>
<div class='new'></div>
Call the function passing the old object as parameter and get the array of objects in required format.