Match Json keys and replace with values in array - javascript

So given a simple json object
[
{"a": 1},
{"b": 2},
{"c": 3},
{"d": 4}
]
and an array like this
var arr = ["A", "B", "C"];
I want to write the most efficient function to match the lower case keys with their upper case counter parts and replace them with the uppercase letters, I started by turning the array into a object so I wont have to iterate over and over again, but Im stuck. Can someone please show me how they would handle this in the most efficient way?

Without further information on your amount of keys/possible keys, trying to make a generic solution would be like this:
var arr = [
{"a": 1},
{"b": 2},
{"c": 3},
{"d": 4}
]
var match = ["A", "B", "C"];
var objMatch = {}
for(var i=0;i<match.length;i++) objMatch[match[i].toLowerCase()] = match[i] // pass it to an object for efficient matching
for(var i=0;i<arr.length;i++){
for(var key in arr[i]){ // check if we need to replace the key
if(objMatch.hasOwnProperty(key)){
var temp = arr[i][key] // keep old value
delete arr[i][key] // delete key
arr[i][objMatch[key]] = temp // set new key with same old value
}
}
}
console.log(arr)

From what i understand from your question
var arrayOne = [
{"a": 1},
{"b": 2},
{"c": 3},
{"d": 4}
];
var arrayTwo = ["A", "B", "C"];
var tempArray = {};
$.each(arrayOne, function(key,value){
for(arrayOneKey in value){
$.each(arrayTwo, function(index,vl) {
if(vl.toLowerCase() == arrayOneKey.toLowerCase()){
tempArray[vl]=key+1;
}
});
}
});
console.log(tempArray);

var a=[
{"a": 1},
{"b": 2},
{"c": 3},
{"d": 4}
];
var arr = ["A", "B", "C"];
Define a method in Object's prototype chain to rename Object keys:
Object.prototype.changeKey = function (oName, nName) {
if (oName == nName) {
return this;
}
if (this.hasOwnProperty(oName)) {
this[nName] = this[oName];
delete this[oName];
}
return this;
};
Then find the key which matches the elements of array, then change it:
for(var i=0;i<arr.length;i++){
for(key in a[i]){
if(key === arr[i].toLowerCase()){a[i].changeKey (key,arr[i])}
}
}
Here is a fiddle

Don't make things complicated. Use map and return a new array:
function transform(arr, keys) {
return arr.map(function(el) {
var obj = {};
var key = Object.keys(el)[0];
var uc = key.toUpperCase();
obj[keys.indexOf(uc) > -1 ? uc : key] = el[key];
return obj;
});
}
transform(input, arr);
DEMO

You could use an helper object and loop throu all items and all keys.
var arr0 = [{ "a": 1 }, { "b": 2 }, { "c": 3 }, { "d": 4 }],
arr1 = ["A", "B", "C"],
obj = Object.create(null);
arr1.forEach(function (a) {
obj[a.toUpperCase()] = a;
});
arr0.forEach(function (a) {
Object.keys(a).forEach(function (k) {
var v = a[k];
if (k.toUpperCase() in obj) {
delete a[k];
a[obj[k.toUpperCase()]] = v;
}
});
});
document.write('<pre>' + JSON.stringify(arr0, 0, 4) + '</pre>');

Related

Replacing multiple elements of an array while keeping their position

Helo guys, I am pretty new to javascript so I seek your help.
My problem is the following:
If have an array like
var arr1 = ["a", "b", "a" "c"];
and I'd like to find and replace each "a" with a certain element of an other array
var arr2 = [1, 2, 3, 4, 5, 6,];
Now how do I replace each "a" with the first element of arr2?
Each "b" with the second and so on.
Is there any possibility of this? With keeping the the position?
You can use an object to associate each character to a specific integer: obj:
const obj = {a:1, b:2, c:3, d:4, e:5, f:6};
Then use the .map method to remap the array arr1 with the helper object obj:
arr1.map(e => obj[e])
The .map method creates a new array with the results of calling a provided function on every element in the calling array.
const arr1 = ["a", "b", "a", "c"];
const obj = {a:1, b:2, c:3, d:4, e:5, f:6};
console.log(
arr1.map(e => obj[e])
)
This way you can change the relationship between the characters and number in by changing obj. You can even set variables as values of obj, for example:
const arr1 = ["a", "b", "a", "c"];
const otherLetter = "z";
const obj = {a:otherLetter, b:2, c:3, d:4, e:5, f:6};
console.log(
arr1.map(e => obj[e])
)
You could take a dynmaic approach and build succesive a hash table and take that value.
var array1 = ["a", "b", "a", "c"],
array2 = [1, 2, 3, 4, 5, 6],
hash = Object.create(null),
index = 0;
result = array1.map(v => v in hash ? hash[v] : hash[v] = array2[index++]);
console.log(result);
A version without index, but with mutating array2
var array1 = ["a", "b", "a", "c"],
array2 = [1, 2, 3, 4, 5, 6],
hash = Object.create(null),
result = array1.map(v => v in hash ? hash[v] : hash[v] = array2.shift());
console.log(result);
this might help you:
var arr1 = ["a", "b", "a", "c", "f"];
var arr2 = [1, 2, 3, 4];
//print out arrays
console.log("arr1: ", arr1);
console.log("arr2: ", arr2);
//loop through the arr1
var i;
//loop until you reach the length of array1.
for (i = 0; i < arr1.length; i++) {
//check type of item in arr1
switch (arr1[i]) {
case "a":
arr1[i] = arr2[0];
break;
case "b":
arr1[i] = arr2[1];
break;
case "c":
arr1[i] = arr2[2];
break;
default:
//default if none of the above cases match with entry in array1
arr1[i] = -1;
}
}
//print out arrays
console.log("arr1: ", arr1);
console.log("arr2: ", arr2);
You can use parseInt to generate indices from the characters in arr1 like this:
let indices = arr1.map(str => parseInt(str, 36) - 10);
The second argument of parseInt is the radix, 36 allows for specifying numbers using 0-9 and a-z. Because a = 10 we need to substract 10 in order to get the proper index (a -> index 0).
And then use these indices to get the according element from arr2:
let result = indices.map(index => arr1[index]);
A small, condensed example:
let arr1 = ['a', 'b', 'a', 'c'],
arr2 = [1, 2, 3, 4, 5, 6],
result = arr1.map(s => parseInt(s, 36) - 10).map(i => arr2[i]);
console.log(result);
You can create a string representation of the arr1 and replace the characters:
var arr1 = ["a", "b", "a", "c"];
var arr2 = [1, 2, 3, 4, 5, 6,];
var str = arr1.join(',');
arr2.forEach((number, index)=>{
var character = arr1[index];
if(character && isNaN(arr1[index])){
var re = new RegExp(character,"g");
str = str.replace(re, number);
}
});
arr1 = str.split(',');
console.log(arr1);
Here's my (much simpler) answer:
var arr1 = ["a", "b", "a", "c"];
//I'd like to find and replace each "a"
//with a certain element of an other array
var arr2 = [1, 2, 3, 4, 5, 6,];
for(var i in arr1) {
arr1[i] = arr2[arr1[i].charCodeAt(0) - 97];
}
console.log('arr1 is now: [' + arr1 + ']');
var arr1 = ["a", "b", "a", "c"];
var arr2 = [1, 2, 3, 4, 5, 6];
var uniqueItems = Array.from(new Set(arr1));
for(i=0;i<uniqueItems.length;i++){
arr1.forEach(function(item, j) { if (item == uniqueItems[i]) arr1[j] = arr2[i]; });
}
console.log(arr1);

Remove all certain objects from an array

Given the array:
myArr = [
{'a':1},
{'b':1},
{'b':2},
{'a':1},
{'b':2}
]
And the index 0, which has the object {'a':1}, I would like to get back the array:
[{'b':1},{'b':2},{'b':2}] keeping the original sort order.
That is removing the object in index 0 and all other objects which are the equivalent.
Is there an elegant way?
If you want to remove the same object, it is simple:
a1 = { a: 1 }
b1 = { b: 1 }
b2 = { b: 2 }
myArr = [ a1, b1, b2, a1, b2 ]
var filtered = myArr.filter(o => o != a1)
console.log(filtered);
// [ {b: 1}, {b: 2}, {b: 2} ]
However, if you want to remove an equivalent object, it gets complicated, because by default JavaScript does not have an object equivalence test. You can implement one yourself, or rely on one of the libraries like lodash:
var myArr = [
{'a':1},
{'b':1},
{'b':2},
{'a':1},
{'b':2}
];
var filtered = _.filter(myArr, o => !_.isEqual(o, {a: 1}));
console.log(filtered);
// [ {b: 1}, {b: 2}, {b: 2} ]
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.6/lodash.min.js"></script>
Then again, if you're using lodash, you might as well just use it to the full extent:
var myArr = [
{'a':1},
{'b':1},
{'b':2},
{'a':1},
{'b':2}
];
var filtered = _.differenceWith(myArr, [{a: 1}], _.isEqual);
console.log(filtered);
// [ {b: 1}, {b: 2}, {b: 2} ]
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.6/lodash.min.js"></script>
which basically does the same thing, but a bit more readably.
This works for me
myArr = [
{'a':1},
{'b':1},
{'b':2},
{'a':1},
{'b':2}
]
//Get first item
for(var key in myArr[0]){
var firstItem = key;
}
alert('First item: ' + firstItem);
//Remove matches
var removedItems = []; //Not needed, just used to show you what it's removing.
myArr.forEach(function(item){
for (var key in item){
if(key == firstItem){
removedItems.push(key); //Not needed
myArr.splice(item, 1); //Remove the array entry
}
}
});
alert('Removed items: ' + removedItems);
try myArr.shift();
It will return {'a':1}
And myArr will be [{'b':1},{'b':2},{'b':2}]

Find single value from multiple values in single array

I have a single array having multiple values in that as shown in code below.
tempstraindatasource
tempstraindatasource[0] = {
A = "0",
B = "1",
C = "2",
D = "3"
}
tempstraindatasource[1] = {
A = "4",
B = "5",
C = "6",
D = "7"
and so on like wise I have many data exist in single array
}
I want to do one procedure that finds the data are consist or not in single line like I want to find Species having name "A" = "0" or any value "B" = "0" or "C" = "0"! How can I do it in single line? Please some one help me to do this.
Thanks in advance and appreciate as well.
You could use Array#forEach for the array and check if any of the properties have the value, you need with Array#some, and push the index then to the result array.
var data = [{ a: 0, b: 1, c: 2, d: 3 }, { a: 4, b: 5, c: 6, d: 7 }],
indices = [];
data.forEach(function (a, i) {
Object.keys(a).some(function (k) {
return a[k] === 0;
}) && indices.push(i);
});
console.log(indices);
As stated in comments your question needs editing (or better a total rewrite) but I think what you need is this
var fruits = [{name: 'banana', cost: 5}, {name: 'apple', cost:2}];
var filteredArray = fruits.map(function(fruit, index){
fruit.index = index;
return fruit;
}).filter(function(fruit){
return fruit.name === 'banana';
});
document.write(JSON.stringify(filteredArray));

Merge two arrays as if shuffling cards without iterating?

In javascript, is there an easy way to merge 2 arrays as if shuffling a deck of cards?
For example:
[ "1", "2", "3" ] +
[ "a", "b", "c" ]
=> [ "1", "a", "2", "b", "3", "c" ]
This action is typically called "zip".
Underscore.js has an implementation of it:
var a1 = [ "1", "2", "3" ];
var a2 = [ "a", "b", "c" ];
var zipped = _.zip(a1, a2);
If you want a random order, you can use shuffle:
var shuffled = _.shuffle(a1.concat(a2));
var arr1 = ["1", "2", "3"];
var arr2 = ["a", "b", "c"];
You can just loop through the arrays and create a new one. This example assumes that arr1 and arr2 are the same length.
var result = (function(a, b){
for(var i = 0, result = []; i < a.length; i++)
result.push(a[i], b[i]);
return result;
})(arr1, arr2);
// result == ["1", "a", "2", "b", "3", "c"]
You can't do it without iterating, but you can hide the iteration behind some array functions.
var a = [ "1", "2", "3" ];
var b = [ "a", "b", "c" ];
// only works if a and b have the same length
var c = a.concat(b).map(function(item, index, arr){
return index % 2 ? arr[arr.length/2 + (index+1)/2 - 1] : arr[index/2];
});
console.log(c);
You can create a closure that can be used as an array for reading (i.e. c(i) returns i-th element of result):
c = function(i){ return [a, b][i & 1][i >> 1]; };
or, probably more efficient, as
c = function(i){ return (i & 1) ? b[i >> 1] : a[i >> 1]; };
The nice thing of this approach is that you don't build all elements at once, but you will just get the element from the original arrays only if requested.
This also allows using functions instead of arrays for a and b:
c = function(i){ return (i & 1) ? b(i >> 1) : a(i >> 1); };

in javascript, is there an easy way to sort key-value pairs by the value, and return the key?

In javascript, is there an easy way to sort key-value pairs by the value (assume the value is numeric), and return the key? A jQuery way to do this would be useful as well.
(There are a lot of related questions about key-value pairs here, but I can't find one specifically about sorting.)
There's nothing easy to do this cross-browser. Assuming an array such as
var a = [
{key: "foo", value: 10},
{key: "bar", value: 1},
{key: "baz", value: 5}
];
... you can get an array of the key properties sorted by value as follows:
var sorted = a.slice(0).sort(function(a, b) {
return a.value - b.value;
});
var keys = [];
for (var i = 0, len = sorted.length; i < len; ++i) {
keys[i] = sorted[i].key;
}
// keys is ["bar", "baz", "foo"];
Let's assume we have an Array of Objects, like:
var data = [
{foo: 6},
{foo: 2},
{foo: 13},
{foo: 8}
];
We can call Array.prototype.sort()help, use Array.prototype.map()help to map a new array and Object.keys()help to grab the key:
var keys = data.sort(function(a,b) {
return a.foo - b.foo;
}).map(function(elem, index, arr) {
return Object.keys(elem)[0];
});
Be aware of, Array.prototype.map() requires Javascript 1.6 and Object.keys() is ECMAscript5 (requires Javascript 1.8.5).
You'll find alternative code for all those methods on MDC.
As far as I know, there isn't a built-in Javascript function to sort an array by its keys.
However, it shouldn't take too much code to do it: just extract the keys into their own array, sort them using the normal sort function, and rebuild the array in the right order. Something like this should do the trick:
function SortArrayByKeys(inputarray) {
var arraykeys=[];
for(var k in inputarray) {arraykeys.push(k);}
arraykeys.sort();
var outputarray=[];
for(var i=0; i<arraykeys.length; i++) {
outputarray[arraykeys[i]]=inputarray[arraykeys[i]];
}
return outputarray;
}
Now you can just call your function like so:
var myarray = {'eee':12, 'blah':34 'what'=>66, 'spoon':11, 'snarglies':22};
myarray = SortArrayByKeys(myarray);
And the output will be:
{'blah':34, 'eee':12, 'spoon':11, 'snarglies':22, 'what':66}
Hope that helps.
Working test page here: http://jsfiddle.net/6Ev3S/
Given
var object = {
'a': 5,
'b': 11,
'c': 1,
'd': 2,
'e': 6
}
You can sort object's keys by their values using the following:
Object.keys(object).sort(function (a, b) {
return object[a] - object[b]
}))
Result
[ 'c', 'd', 'a', 'e', 'b' ]
If you can't count on the exended array and object properties,
you can use the original Array methods-
function keysbyValue(O){
var A= [];
for(var p in O){
if(O.hasOwnProperty(p)) A.push([p, O[p]]);
}
A.sort(function(a, b){
var a1= a[1], b1= b[1];
return a1-b1;
});
for(var i= 0, L= A.length; i<L; i++){
A[i]= A[i][0];
}
return A;
}
//test
var Obj={a: 20, b: 2, c: 100, d: 10, e: -10};
keysbyValue(Obj)
/* returned value: (Array)
e,b,d,a,c
*/

Categories