How can I replace property names inside of an object? Javascript - javascript

My task is to create a function that swaps the names inside of the object with the names inside of an array.
Daniel's name should change to Felix and his age should remain the same. In the end, the object should look like this.
{Felix:18,Carlos:21,Sasha:22,John:20}
From This
{Daniel:18,Tyler:21,Michelle:22,Austin:20}
Heres what I have so far. I am new to programming so please try to take it easy on me.
function swapNames(oldNames,newNames){
for(var i in oldNames) {
for(var k = 0; k < newNames.length; k++) {
i = newNames[k];
}
}
console.log(i)
}
swapNames({Daniel:18,Tyler:21,Michelle:22,Austin:20},
["Felix","Carlos","Sasha","John"])
I thought this would loop through the object and the array and set the objects property name to the current string I am on. But when I console.log() the object is exactly the same.

Here is what you could do.
const swapNames = (inputObj, outputNames) => {
const output = {};
Object.keys(inputObj).forEach((key, index) => {
output[outputNames[index]] = inputObj[key];
});
return output;
}
console.log(swapNames({
Daniel: 18,
Tyler: 21,
Michelle: 22,
Austin: 20
}, ["Felix", "Carlos", "Sasha", "John"]));

I don't want give away the answer, but your problem is here
for(var i in oldNames) {
// when i = Daniel;
for(var k = 0; k < newNames.length; k++) {
i = newNames[k];
// you loop here keep change i from Daniel to "Felix","Carlos","Sasha","John",
// then you go back to above loop and repeat this, so all four old name got stuck with John
}
console.log(i)
}

Related

JS multidimensional array spacefield

i wanna generate a 3x3 field. I want to do this with JS, it shall be a web application.
All fields shall inital with false. But it seems so that my code is not working correctly, but i don't find my fault. The goal is, that every spacesector is accessible.
Thats my idea:
// define size
var esize = generateSpace(3);
}
space[i] = false is replacing the array with a single boolean value false, not filling in all the entries in array you just created. You need another loop to initialize all the elements of the array.
function generateSpace(x) {
var space = [];
for (var i = 0; i < x; i++) {
space[i] = [];
for (var j = 0; j < x; j++) {
space[i][j] = false;
}
}
return space;
}
Also, your for() loop condition was wrong, as you weren't initializing the last element of space. It should have been i < space.length.
And when it's done, it needs to return the array that it created.
Since I got somewhat bored and felt like messing around, you can also initialize your dataset as shown below:
function generateSpace(x) {
return Array.apply(null, Array(x)).map(function() {
return Array.apply(null, Array(x)).map(function() {
return false;
});
});
}
The other functions work equally well, but here's a fairly simply looking one using ES6 that works for any square grid:
function generateSpace(x) {
return Array(x).fill(Array(x).fill(false));
}

Add a value to each element in javascript

Is there a good way to add a certain value to each element in an array in javascript? Essentially, this should be a better way of writing the following:
a = [1,2,3,4];
for (i = 0; i < a.length; i++) {
a[i] += 7;
}
Maybe using map (but not necessarily)?
Edit:
Or a more interesting example:
a = [{'x':1},{'x':2},{'x':3},{'x':4}];
for (i = 0; i < a.length; i++) {
a[i].x += 7;
}
You can use map to do it:
a = a.map(function(entry) {
return entry + 7;
});
I'm not seeing how it's "better" to create a new array rather than update the one you have.
You can also use forEach:
a.forEach(function(entry, index) {
a[index] += 7;
});
It's still a bunch of function calls (but that's not a problem), but you have the advantage (over a for loop) of not having to declare the indexing variable, and you're modifying the existing array rather than replacing it.
Edit: Your "most interesting" example says even more that map is not really the best choice.
a.forEach(function(entry) {
entry.x += 7;
});
Yes, you can use .map but it will not modify the array in-place, so you must assign the result to a:
a = a.map(function(x) { return x+7 });

Better solution to find a cell in an array

I have the following array:
var myArray = [
{
"id":1,
"name":"name1",
"resource_uri":"/api/v1/product/1"
},
{
"id":5,
"name":"name2",
"resource_uri":"/api/v1/product/5"
}
]
Each row is identified by it's unique id. I am quite new to Javascript and was wondering what was the best solution to find a cell based on id.
For example, for the id:5; my function must return:
findCell(myTable, id=5);
// this function must return:
{
"id":5,
"name":"name2",
"resource_uri":"/api/v1/product/5"
}
I'm quite afraid to do an ugly for loop... Maybe there is some built-in javascript function to perform such basic operations.
Thanks.
Yes there is a built-in function - filter. I would use it like this:
findCells(table, property, value) {
return table.filter(function (item) {
return item[property] === value;
});
}
findCells(myTable, "id", 5);
This is a bit modified version, of what you want: it can find all cells by the specified property name value.
Edit: using for loop to search the first occurence of the element is okay, actually:
findCell(table, id) {
var result = null;
for (var i = 0, cell = table[0], l = table.length; i < l; i++, cell = table[i]) {
if (cell.id === id) {
result = cell;
break;
}
}
return result;
}
findCell(myTable, 5);
Try this expression this might be helpful
var result = myArray.filter(function(element, index) { return element.ID == 5; });
filter() has two parameters
element - current row
index - current row index.
If you are going to stick with the array, the 'ugly' for loop is your best bet for compatibility. It's not that ugly when put in a function:
function findById(id) {
for(var i = 0; i < myArray.length; ++i) {
if(myArray[i].id === id) return myArray[i];
}
}
// Not checking return value here!
alert(findById(5).name);
Filter is another option if your concern is only with recent versions of browsers. It will return an array of values.
If your array is very large though, it would make sense to introduce some sort of index for efficient lookups. It adds an additional maintenance burden, but can increase performance for frequent lookups:
var index = {};
for(var i = 0; i < myArray.length; ++i) {
index[myArray[i].id] = i;
}
// Find element with id=5
alert(myArray[index[5]].name);
Example

Can I select 2nd element of a 2 dimensional array by value of the first element in Javascript?

I have a JSON response like this:
var errorLog = "[[\"comp\",\"Please add company name!\"],
[\"zip\",\"Please add zip code!\"],
...
Which I'm deserializing like this:
var log = jQuery.parseJSON(errorLog);
Now I can access elements like this:
log[1][1] > "Please add company name"
Question:
If I have the first value comp, is there a way to directly get the 2nd value by doing:
log[comp][1]
without looping through the whole array.
Thanks for help!
No. Unless the 'value' of the first array (maybe I should say, the first dimension, or the first row), is also it's key. That is, unless it is something like this:
log = {
'comp': 'Please add a company name'
.
.
.
}
Now, log['comp'] or log.comp is legal.
There are two was to do this, but neither avoids a loop. The first is to loop through the array each time you access the items:
var val = '';
for (var i = 0; i < errorLog.length; i++) {
if (errorLog[i][0] === "comp") {
val = errorLog[i][1];
break;
}
}
The other would be to work your array into an object and access it with object notation.
var errors = {};
for (var i = 0; i < errorLog.length; i++) {
errors[errorLog[i][0]] = errorLog[i][1];
}
You could then access the relevant value with errors.comp.
If you're only looking once, the first option is probably better. If you may look more than once, it's probably best to use the second system since (a) you only need to do the loop once, which is more efficient, (b) you don't repeat yourself with the looping code, (c) it's immediately obvious what you're trying to do.
No matter what you are going to loop through the array somehow even it is obscured for you a bit by tools like jQuery.
You could create an object from the array as has been suggested like this:
var objLookup = function(arr, search) {
var o = {}, i, l, first, second;
for (i=0, l=arr.length; i<l; i++) {
first = arr[i][0]; // These variables are for convenience and readability.
second = arr[i][1]; // The function could be rewritten without them.
o[first] = second;
}
return o[search];
}
But the faster solution would be to just loop through the array and return the value as soon as it is found:
var indexLookup = function(arr, search){
var index = -1, i, l;
for (i = 0, l = arr.length; i<l; i++) {
if (arr[i][0] === search) return arr[i][1];
}
return undefined;
}
You could then just use these functions like this in your code so that you don't have to have the looping in the middle of all your code:
var log = [
["comp","Please add company name!"],
["zip","Please add zip code!"]
];
objLookup(log, "zip"); // Please add zip code!
indexLookup(log, "comp"); // Please add company name!
Here is a jsfiddle that shows these in use.
Have you looked at jQuery's grep or inArray method?
See this discussion
Are there any jquery features to query multi-dimensional arrays in a similar fashion to the DOM?

Merge loops with jQuery.extend: last value is always the same?

I have two arrays of "hashes". I need to merge them together so the end result is another array of hashes, except the number of entries is the product of the two arrays.
inhabitants = {}
idx = 0
for (i=0; i<persons.length; i++) {
person = persons[i];
for (j=0; j<houses.length; j++) {
house = houses[j];
console.log(house);
inhabitants[idx] = $.extend(person,house);
console.log(inhabitants[idx]);
idx++;
}
}
What I end up with is a silly number of entries that depends on the ordering of the parameters in the $.extend() line. And the "house" entry that is added is ALWAYS THE LAST ENTRY IN THE ARRAY.
Clearly this $.extend() from jQuery is not doing what I expect. Can anyone help?
$.extend(a, b) merges b into a, and returns a.
The return value you're using but it seems you were missing the fact that a is also being changed - you're currently assigning the same variable person to inhabitants[idx] each time.
I'm not really getting what you are trying to do, but anyway just a few hints. It's a good idea to place all the semicolons (here they're missing in the first and second line). Then I don't see why you are using an object instead of an array where you just have to push new items. Another thing is that in js it is faster to cache the lengths of the persons and houses collections. I will try to come up with code how I understood your task, maybe I'm getting it wrong:
var inhabitants = [],
idx = 0,
personCount = persons.length,
houseCount = houses.length,
person = {},
house = {},
i = 0,
j = 0;
for (i = 0; i < personCount; i++) {
person = persons[i];
for (j = 0; j < houseCount; j++) {
house = houses[j];
inhabitants.push($.extend({}, person, house);
}
}
So to me it seems like a database join between the two tables persons and houses. Is this what you meant?

Categories