Finding field.value in JSON array - javascript

var x = [{ a: 1, b: 2}, { a: 11, b: 12}, { a: 31, b: 23}, { a: 51, b: 24}]
how do you find a = 11 ?
for simple arrays one can do x.indexOf('1'); so perhaps the solution should be something like
var a1 = x.indexOf({a: 1});
ofcourse, I want to obtain the entire JSON for which the value matches.

you can do it with a simple function, no third party modules needed:
var x = [{ a: 1, b: 2}, { a: 11, b: 12}, { a: 31, b: 23}, { a: 51, b: 24}];
function getIndexOf(value){
for(var i=0; i<x.lengh; i++){
if(x[i].a == value)
return i;
}
}
alert(getIndexOf(value)); // output is: 1

You can use Array.Filter with shim support on older browsers.
var x = [{
a: 1,
b: 2
}, {
a: 11,
b: 12
}, {
a: 31,
b: 23
}, {
a: 51,
b: 24
}],
tocomp = 11;
var res = x.filter(function (ob) {
return ob.a === tocomp;
});
Result will be array of object that matches the condition.
Fiddle
And if you just care for single match and get back the matched object just use a for loop.
var x = [{
a: 1,
b: 2
}, {
a: 11,
b: 12
}, {
a: 31,
b: 23
}, {
a: 51,
b: 24
}],
tocomp = 11, i, match;
for (i=0, l=x.length; i<l; i++){
if(x[i].a === tocomp){
match = x[i];
break; //break after finding the match
}
}

Simply iterate over the array to get the value.
for(var i = 0;i < x.length; i++){
alert(x[i].a);
}
JsFiddle

You can use native js or you can use underscoreJS lib.
UnderscoreJS

Related

How to find the number that best matches a given number

How to find the most suitable number for a given number.
For example. I have a number 8 and an array of objects.
let num = 8;
let data = [
{ fist: {a: 1, b: 2}, second: {c: 11, d: 12}, number: 1 },
{ fist: {a: 3, b: 4}, second: {c: 13, d: 14}, number: 7 },
{ fist: {a: 5, b: 6}, second: {c: 15, d: 16}, number: 10 },
];
The closest number of all numbers in each object is 7.
How can I display the whole obit to which the number 7 belongs?
You can use .reduce to get the obj with minimum distance from num:
let num = 8;
let data = [
{ fist: {a: 1, b: 2}, second: {c: 11, d: 12}, number: 1 },
{ fist: {a: 3, b: 4}, second: {c: 13, d: 14}, number: 7 },
{ fist: {a: 5, b: 6}, second: {c: 15, d: 16}, number: 10 },
];
const _isEmpty = (obj) => Object.keys(obj).length === 0;
const objWithClosestNumber = data.reduce((acc, item) => {
if(_isEmpty(acc)) { return item };
const closestDist = Math.abs(num - acc.number),
currentDist = Math.abs(num - item.number);
acc = (currentDist < closestDist) ? item : acc;
return acc;
}, {});
console.log(objWithClosestNumber);
Traverse the array and find the smallest difference.
let num = 8;
let data = [
{ fist: { a: 1, b: 2 }, second: { c: 11, d: 12 }, number: 1 },
{ fist: { a: 3, b: 4 }, second: { c: 13, d: 14 }, number: 7 },
{ fist: { a: 5, b: 6 }, second: { c: 15, d: 16 }, number: 10 },
];
let diff = Math.abs(num - data[0].number);
let ret = data[0];
data.forEach((x) => {
if (diff > Math.abs(x.number - num)) {
diff = Math.abs(x.number - num);
ret = x;
}
});
console.log(ret);
You could reduce the array by choosing the item with the smaller absolute delta of given value and wanted value .
let num = 8,
data = [{ fist: { a: 1, b: 2 }, second: {c: 11, d: 12 }, number: 1 }, { fist: { a: 3, b: 4 }, second: { c: 13, d: 14 }, number: 7 }, { fist: { a: 5, b: 6 }, second: { c: 15, d: 16 }, number: 10 }],
result = data.reduce((a, b) =>
Math.abs(num - a.number) < Math.abs(num - b.number) ? a : b
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Plain JS or Lodash - replace object values with values from other object

I have two objects:
let first = {
a: 'John',
b: 22,
c: 'example'
}
let second = {
b: 55,
d: 'demo'
}
I want to replace only already existing items from second object to first one. Result should look like this (so only b item should be changed, and new d item ignored):
{
a: 'John',
b: 55, // changed
c: 'example'
}
Merge will not work because it will add also new item.
I can use foreach but I believe that there should be shorted answer for this. I'm already using lodash in my project so I can use function from there, but I cannot find any for this purpose. Is there any?
With lodash you could do something like this with _.merge, _.pick and _.keys:
let first = {
a: 'John',
b: 22,
c: 'example'
}, second = {
b: 55,
d: 'demo'
}
let result = _.merge(first, _.pick(second, _.keys(first)))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
With ES6 you can use Object.keys and then Array.forEach on a new object like this:
let first = {
a: 'John',
b: 22,
c: 'example'
}, second = {
b: 55,
d: 'demo'
}, result = new Object(null)
Object.keys(first).forEach(k => result[k] = second[k] || first[k])
console.log(result)
This assumes you do not want to mutate any of the objects. IF you do not care:
let first = {
a: 'John',
b: 22,
c: 'example'
}, second = {
b: 55,
d: 'demo'
}
Object.keys(first).forEach(k => first[k] = second[k] || first[k])
console.log(first)
You could use this if you use ES6
let merge = { ...first, ..._.pick(second, Object.keys(first)) }
You can use a loop over the keys in the second array. For any keys that exist in the first, overwrite the value.
let first = {
a: 'John',
b: 22,
c: 'example'
}
let second = {
b: 55,
d: 'demo'
}
for (const k in second) {
if (k in first) {
first[k] = second[k];
}
}
console.log(first);
You want to update the values of the
intersection
of the properties.
So basically something like:
Object.keys(a).forEach(prop => if(b.hasOwnProperty(prop)) a[prop] = b[prop]))
Or
_.intersection(Object.keys(a), Object.keys(b)).forEach(prop => a[prop] = b[prop])
let first = {
a: 'John',
b: 22,
c: 'example'
}
let second = {
b: 55,
d: 'demo'
}
Object.keys(second).forEach(function(key,index){
if (first.hasOwnProperty(key)) {
first[key]=second[key];
}
});
console.log(first);
With Lodash two functions MergeWith and Pick
var a = {
a: 'John',
b: 22,
f:[11,22,2],
d: {a:1,b:2,c:0},
c: 'example'
}
var b = {
b: 55,
f:[3],
d: {c:1,b:11},
}
function mergeObjects(a,b){
let common = _.pick(b, Object.keys(a));
return _.mergeWith(a, common, customizer)
}
function customizer(objValue, srcValue) {
if (_.isArray(objValue)) {
return objValue.concat(srcValue);
}
if(_.isObject(objValue)) {
return mergeObjects(objValue,srcValue)
}
}
mergeObjects(a,b)

Javascript findIndex for duplicate values

JavaScript findIndex returns the very first finded index in case of duplicate values
const arr = [{a: 10, b: 20, c: 30},{a: 15, b: 25, c: 32},{a: 10, b: 23, c: 350}]
const index = arr.findIndex(m => m.a === 10)
console.log(index);
The above code will only return 0 index.
What should I do to get index 2 as well.
You could filter the keys of the array like this:
const arr = [{a: 10, b: 20, c: 30},{a: 15, b: 25, c: 32},{a: 10, b: 23, c: 350}]
const indices = [...arr.keys()].filter(i => arr[i].a === 10)
console.log(indices)
Or, just use a for loop
const arr = [{a: 10, b: 20, c: 30},{a: 15, b: 25, c: 32},{a: 10, b: 23, c: 350}]
const output = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i].a === 10)
output.push(i)
}
console.log(output)
arr.reduce((result, current, index) => {
return result.concat(current.a == 10 ? [index]: [])
})
You can use of Array.reduce to loop on your arr and returns every indexes
Single line :
const arr = [{
a: 10,
b: 20,
c: 30,
}, {
a: 15,
b: 25,
c: 32,
}, {
a: 10,
b: 23,
c: 350,
}]
// Value to check for
const v = 10;
// we loop on every entry of the arr
// we start with an empty array and look if the entries
// contains the value 10, if they do, we push the index of the
// entry in the array that was empty
//
// we do that for every entry of arr, when we treat all, we return
// the list of matching entries
const idx = arr.reduce((tmp, x, xi) => (x.a === v ? [...tmp, xi] : tmp), []);
console.log(idx);
Explained :
const arr = [{
a: 10,
b: 20,
c: 30,
}, {
a: 15,
b: 25,
c: 32,
}, {
a: 10,
b: 23,
c: 350,
}]
const valToCheck = 10;
const indexes = arr.reduce((tmp, x, xi) => {
if (x.a === valToCheck) {
tmp.push(xi);
}
return tmp;
}, []);
console.log(indexes);
Use map and filter:
const arr = [{a: 10, b: 20, c: 30},{a: 15, b: 25, c: 32},{a: 10, b: 23, c: 350}];
const res = arr.map(({ a }, i) => a == 10 ? i : "").filter(String);
console.log(res);
You could map the indices of the found items and filter only valid indices.
const
array = [{ a: 10, b: 20, c: 30 }, { a: 15, b: 25, c: 32 }, { a: 10, b: 23, c: 350 }],
indices = array
.map((m, i) => m.a === 10 ? i : -1)
.filter(i => i != -1);
console.log(indices);
You can just iterate through array and push matching index in new array.
const arr = [{a: 10, b: 20, c: 30},{a: 15, b: 25, c: 32},{a: 10, b: 23, c: 350}]
let p = []
arr.forEach((ele,index)=> ele.a===10 ? p.push(index) : '')
console.log(p)
You can try like this:
const arr = [{a: 10, b: 20, c: 30},{a: 15, b: 25, c: 32},{a: 10, b: 23, c: 350}];
const indices = arr.map((x, index) => {
if (x.a === 10) {
return index;
}
})
.filter(x => x !== undefined);
console.log(indices);
If you want a function which works directly with Array, add this in Array.prototype
Array.prototype.findAllIndexes = function(iteratee){
var resultArray = [];
this.forEach(function(element) {
var validated = iteratee.call(this, element);
if(validated) {
resultArray.push(element);
}
});
return resultArray;
}
Then you can use it anywher you want with array object
(please handle your corner cases based od data type you use)
const arr = [{a: 10, b: 20, c: 30},{a: 15, b: 25, c: 32},{a: 10, b: 23, c: 350}]
const index = arr.findAllIndexes(m => m.a === 10)
console.log(index);
You can use some helper libraries to this kind of stuff like lodash.js, you can include them in your project.

Merge objects from two different type arrays

imagine that, we have two arrays. Each of the containing objects of different type. For example:
let first: Foo[] = [
{ a: 12, b: 'x', c: 0 },
{ a: 43, b: 'y', c: 0 }
];
let second: number[] = [11, 15];
I would like merge theirs objects in a way that I finally get one array looks like below:
let first: Foo[] = [
{ a: 12, b: 'x', c: 11 },
{ a: 43, b: 'y', c: 15 }
];
As you can see I just want to assign value from the second array to c property of object from first array.
I hope that you understand my explanation of problem. I believe in your skills, guys!
you could zip the two arrays into one,
const first: Foo[] = [
{ a: 12, b: 'x', c: 0 },
{ a: 43, b: 'y', c: 0 }
];
const second: number[] = [11, 15];
const result: Foo[] = first.map((e, i) => {
return <Foo>Object.assign({}, e, { c: second[i] });
});
As so often, Array.prototype.reduce provides a good base for an approach like e.g. this one ...
var listOfItems = [
{ a: 12, b: 'x', c: 0 },
{ a: 43, b: 'y', c: 0 }
];
var listOfValues = [11, 15];
function reassignValueToGivenKey(collector, item, idx) {
item = Object.assign({}, item); // do not mutate original reference.
item[collector.key] = collector.valueList[idx]; // reassign value.
collector.itemList.push(item); // collect processed items separately.
return collector;
}
var result = listOfItems.reduce(reassignValueToGivenKey, {
key: 'c',
valueList: listOfValues,
itemList: []
}).itemList;
console.log('listOfItems : ', listOfItems);
console.log('result : ', result);
.as-console-wrapper { max-height: 100%!important; top: 0; }
I think you should do it like this...
Maybe not the best, but should work in you case :)
This is very simple...
for(var i in second){
var elem = second[i];
first[i]['c'] = elem;
}

Javascript / jQuery how to filter object with retaining its keys?

I want to have something like this: getting another object without some properties. I already have a working solution:
var s = {
a: 3,
b: 2,
c: -1,
d: 8,
e: -1
};
var f = {};
jQuery.map(s, function(v,k) {
if (v != -1)
{
f[k] = v;
}
});
output is:
a: 3,
b: 2,
d: 8,
its fine but isnt there more simpler sollution? Maybe with jQuery but neither .map, .filter, .grep methods helped me so far!
This may help
var s = {
a: 3,
b: 2,
c: -1,
d: 8,
e: -1
};
for(var k in s){
if(s[k] == -1){
delete(s[k]);
}
}
console.log(s);
You can so something like this
var s = {
a: 3,
b: 2,
c: -1,
d: 8,
e: -1
};
for (var property in s) {
if (s[property]!=-1) {
console.log(property+":"+s[property]);
}
}
You could use delete operator for deleting a property of an object.
var s = { a: 3, b: 2, c: -1, d: 8, e: -1 }
Object.keys(s).forEach(function (k) {
if (s[k] === -1) {
delete s[k];
}
});
console.log(s);

Categories