To merge two object in to a single. I have this array
var input= [
{
code:"Abc",
a:10
},
{
code:"Abc",
a:11
},
{
code:"Abcd",
a:11
}
]
I need Output as
[
{code:"Abc",a:[10,11]},
{code:"Abcd",a:[11]},
]
Please help
function merge(anArray){
var i, len = anArray.length, hash = {}, result = [], obj;
// build a hash/object with key equal to code
for(i = 0; i < len; i++) {
obj = anArray[i];
if (hash[obj.code]) {
// if key already exists than push a new value to an array
// you can add extra check for duplicates here
hash[obj.code].a.push(obj.a);
} else {
// otherwise create a new object under the key
hash[obj.code] = {code: obj.code, a: [obj.a]}
}
}
// convert a hash to an array
for (i in hash) {
result.push(hash[i]);
}
return result;
}
--
// UNIT TEST
var input= [
{
code:"Abc",
a:10
},
{
code:"Abc",
a:11
},
{
code:"Abcd",
a:11
}
];
var expected = [
{code:"Abc",a:[10,11]},
{code:"Abcd",a:[11]},
];
console.log("Expected to get true: ", JSON.stringify(expected) == JSON.stringify(merge(input)));
You need to merge objects that have the same code, so, the task is simple:
var input = [
{
code:"Abc",
a:10
},
{
code:"Abc",
a:11
},
{
code:"Abcd",
a:11
}
];
// first of all, check at the code prop
// define a findIndexByCode Function
function findIndexByCode(code, list) {
for(var i = 0, len = list.length; i < len; i++) {
if(list[i].code === code) {
return i;
}
}
return -1;
}
var result = input.reduce(function(res, curr) {
var index = findIndexByCode(curr.code, res);
// if the index is greater than -1, the item was already added and you need to update its a property
if(index > -1) {
// update a
res[index].a.push(curr.a);
} else {
// otherwise push the whole object
curr.a = [curr.a];
res.push(curr);
}
return res;
}, []);
console.log('result', result);
Related
I have an array like this;
var specialOne = 3;
var array = [{value:"special"},{value:"1"},{value:"2"},{value:"specialOne"},{value:"4"},{value:"special"}];
And I need to convert it to this array;
var temp = [{value:"0"},{value:"1"},{value:"2"},{value:"3"},{value:"4"},{value:"5"}];
special's should be replaced with the appropriate value.
specialOne should be replaced with the given number.
How can i do this ?
More examples:
0,special,2,special,4,5 => 0,1,2,3,4,5
7,8,9,special => 7,8,9,10
special,special,10 => 8,9,10
Maybe this is what you are after
var specialOne = 3;
var array1 = [{value:"special"},{value:"1"},{value:"2"},{value:"specialOne"},{value:"4"},{value:"special"}];
function addspec(specialOne){
array1.forEach((o,i)=>{
if(o.value=="specialOne")o.value = specialOne.toString()
if(o.value=="special") o.value = array1[i-1]?(parseInt(array1[i-1].value)+1).toString():"0"
})
}
addspec(3)
console.log(array1)
This may help you
var specialOne = 3;
var array = [
{ value: "special" },
{ value: "1" },
{ value: "2" },
{ value: "specialOne" },
{ value: "4" },
{ value: "special" }
];
for (i = 0; i < array.length; i++) {
if (array[i].value == 'specialOne') {
array[i].value = String(specialOne);
console.log(array);
} else if (array[i].value == 'special') {
array[i].value = String(0);
array.pop()
array.push( { value: String(5) } );
}
}
for (let i = 0; i < array.length; i++) {
if (array[i].value === "special") array[i].value = i.toString();
if (array[i].value === "specialOne") array[i].value = specialOne.toString();
};
When you need to modify an array you should try to use a 'for' loop first. It is the most efficient as it will not modify the index of the array and will not return a new array (Imagine you have to 10 000 items to modify in your array... ).
Here it's very simple, you itere the array, if the condition match you modify the value (of the array itself).
Something like this?
var specialOne = 3;
var array = [{
value: "special"
}, {
value: "1"
}, {
value: "2"
}, {
value: "specialOne"
}, {
value: "4"
}, {
value: "special"
}];
function getValues(array) {
let counterSync = 0;
let backCheck = [];
let inFlow = false;
let backCheckOnce = false;
return array.map((m, i) => {
if (isNaN(parseInt(m.value))) {
if (inFlow || window[m.value]) {
m.value = "" + (window[m.value] || (counterSync + 1));
} else {
if (i === 0) {
backCheckOnce = true;
}
backCheck.push(m);
}
} else {
inFlow = true;
// do reverse check only once
if (backCheckOnce) {
backCheck.reverse().forEach((x, idx) => x.value = "" + (+m.value - 1));
backCheckOnce = false;
}
}
counterSync = +m.value;
return m;
});
}
console.log(getValues(array));
I have an array with below elements. I am trying to create an object from the array
var arr = [
'find({ qty: { $lt: 20 } } )',
'limit(5)',
'skip(0)'
]
Below is my code. where I am getting only values as the output. Any help on this will be helpful
for (var i = 0; i < arr.length; i++) {
var res = arr[i].search(/\(/ig)
if (res!= -1) {
var result = arr[i].split("(");
result = result[1].slice(0, -1))
}
}
Expected Output
{
"action": "find",
"value": "{ qty: { $lt: 20 } }",
"limit": 5,
"skip": 0
}
match is better than split for this kind of stuff
var arr = [
'find({ qty: { $lt: 20 } } )',
'limit(5)',
'skip(0)'
]
var obj = {};
arr.forEach(function(x, n) {
var m = x.match(/(\w+)\(\s*(.+?)\s*\)/);
if(n == 0) {
obj.action = m[1];
obj.value = m[2];
} else
obj[m[1]] = m[2];
});
document.write("<pre>" + JSON.stringify(obj,0,3));
see this fiddle
Just check if element is first in array, if yes, set action and value keys to splitted array, else just assign splitted values to key and value respectively
var arr = [
'find({ qty: { $lt: 20 } } )',
'limit(5)',
'skip(0)'
]
var result = {};
for (var i = 0; i < arr.length; i++) {
var res = arr[i].split("(")
console.log(res)
result[res[0]] = res[1].split(')')[0]
}
document.write(JSON.stringify(result))
Given data such as :
var people = [
{ 'myKey': 'John Kenedy', 'status': 1 },
{ 'myKey': 'Steeven Red', 'status': 0 },
{ 'myKey': 'Mary_Kenedy', 'status': 3 },
{ 'myKey': 'Carl Orange', 'status': 0 },
{ 'myKey': 'Lady Purple', 'status': 0 },
... // thousands more
];
How to efficiently get the list of all objects which contains in myKey the string Kenedy ?
http://jsfiddle.net/yb3rdhm8/
Note: I currently use str.search() :
The search("str") returns the position of the match. Returns -1 if no match is found.
to do as follow :
var map_partial_matches = function(object, str){
var list_of_people_with_kenedy = [] ;
for (var j in object) {
if (object[j]["myKey"].search(str) != -1) {
object[j].presidentName = "yes"; // do something to object[j]
list_of_people_with_kenedy.push({ "people": object[j]["myKey"] }); // add object key to new list
}
} return list_of_people_with_kenedy;
}
map_partial_matches(people, "Kenedy");
I could do the same using str.match() :
str.match() returns the matches, as an Array object. Returns null if no match is found.
It works anyway, but I have no idea if it's efficient or completely dump.
You can use filter():
var filtered = people.filter(function (item) {
if (item.myKey.indexOf("Kenedy") != -1)
return item;
});
You can also checkout Sugar.js
In order to search your unsorted object you need to get through all of it's properties - So I'd say a simple loop with an indexOf will be pretty much the best you can go:
var foundItems = [];
for(var i = 0; i < people.length ;i++)
{
if(people[i].myKey.indexOf('Kenedy') > -1)
foundItems.push(people[i]]);
}
Maybe you can tweak it up a little, but it's pretty much the best you can get.
You can write a basic function that uses filter to return an array of matches based on a key and value:
function find(arr, key, val) {
return arr.filter(function (el) {
return el[key].indexOf(val) > -1;
});
}
var result = find(people, 'myKey', 'Kenedy');
Alternatively use a normal for...loop:
function find(arr, key, val) {
var out = [];
for (var i = 0, l = arr.length; i < l; i++) {
if (arr[i][key].indexOf(val) > -1) {
out.push(arr[i]);
}
}
return out;
}
DEMO
Does the Object Contain a Given Key?
function hKey(obj, key) {
arr = [];
// newarr =[];
for(el in obj){
arr.push(el)
} //return arr;
for(i=0; i<arr.length; i++){
name = arr[i]
} if(name == key) {
return true;
}else {
return false;
}
}
console.log(hKey({ a: 44, b: 45, c: 46 }, "c"))
I have json array is as below
[
{
French: 'Hello',
Spanish: 'Hello1',
english:'Hello2'
},{
French: 'Hello3',
Spanish: 'Hello4',
english:'Hello5'
},{
French: 'Hello6',
Spanish: 'Hello7',
english:'Hello8'
},{
French: 'Hello9',
Spanish: 'Hello10',
english:'Hello81'
}
];
In Javascript array If I wanted to search items based on values
ex If I give Hello6 as finding string I should get 3rd item in the list. I would like generic search rather searching each and every element.
You can try this:
function findIndex(arr, str) {
for (var i = 0; i < arr.length; i++) {
for (var key in arr[i]) {
if (arr[i][key] === str) {
if (arr[i].hasOwnProperty(key) {
return arr[i];
}
}
}
}
return null;
}
This method consists of an array search with a normal for loop and then, for each element of this array, we perform a for..in loop.
Here is my sample using native functions:
var items = [/*your sample*/];
var myValue = "Hello6";
var result = items.filter(function (item) {
return Object.keys(item).some(function (property) {
return item[property] === myValue;
});
});
you can use filter function:
var val = "Hello6";
//if you want to filter the array
resultArray = jsonArray.filter(function(obj, index){
for(var key in obj){
if(obj[key]==val) return obj;
}
});
var indexes=[];
//if you want to find the results
jsonArray.forEach(function(obj, index){
for(var key in obj){
if(obj[key]==val){
indexes.push(index);
break;
}
}
});
You could use good old for loops :
function find(array, fn) {
for (var i = 0, l = array.length; i < l; i++) {
if (fn(array[i]) === true) return array[i];
}
}
Usage example :
var a = [{ a: 1 }, { a: 2 }, { a: 3 }];
var result = find(a, function (item) {
return item.a === 2;
});
result; // { a: 2 }
With a more complex array :
var a = [
{ a: 1, b: 2 },
{ a: 3, b: 4 },
{ a: 5, b: 6 }
];
var result = find(a, function (item) {
for (var k in item) {
if (item[k] === 4) return true;
}
});
result; // { a: 3, b: 4 }
I think the title explains it well enough. I've got an array that has two values per object and I need to look up the object by one of those values then assign a third to it.
Here are the guts:
$slides.push({
img: el.attr('href'),
desc: el.attr('title').split('Photo #')[1]
});
Which builds an array as such:
Object
desc: 127
img: img/aaron1.jpg
Object
desc: 128
img: img/aaron2.jpg
I'd like to look up the desc value, then assign a third value of in: yes
$slides.findInArray('desc', '127').addValueToObject('in','yes')
http://jsfiddle.net/S3cpa/
var test = [
{
desc: 127,
img: 'img/aaron1.jpg',
},
{
desc: 128,
img: 'img/aaron2.jpg',
}
];
function getObjWhenPropertyEquals(prop, val)
{
for (var i = 0, l = test.length; i < l; i++) {
// check the obj has the property before comparing it
if (typeof test[i][prop] === 'undefined') continue;
// if the obj property equals our test value, return the obj
if (test[i][prop] === val) return test[i];
}
// didn't find an object with the property
return false;
}
// look up the obj and save it
var obj = getObjWhenPropertyEquals('desc', 127);
// set the new property if obj was found
obj.in = obj && 'yes';
easy way
for (var i = 0; i < $slides.length; i++)
{
if ($slides[i]["desc"] == "TEST_VALUE")
{
$slides[i]['in']='yes';
}
}
Another way
Array.prototype.findInArray =function(propName,value)
{
var res={};
if(propName && value)
{
for (var i=0; i<this.length; i++)
{
if(this[i][propName]==value)
{
res = this[i];
break;
}
}
}
return res;
}
Object.prototype.addValueToObject =function(prop,value)
{
this[prop]=value;
}
---Using It--
$slides.findInArray('desc', '127').addValueToObject('in','yes');
http://jsfiddle.net/s6ThK/
You need to run it through a for loop
// Loop through the array
for (var i = 0 ; i < $slides.length ; i++)
{
// Compare current item to the value you're looking for
if ($slides[i]["desc"] == myValue)
{
//do what you gotta do
$slides[i]["desc"] = newValue;
break;
}
}
With modern JS it can be simply done:
var obj = $slides.find(e => e.desc === '127');
if (obj) {
obj.in = 'yes';
}