# Mapping a specific data of an array of properties in JSON

**URL:** <https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092>\
**Category:** General\
**Created:** [16 February 2021 14:46 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092 "2021-02-16T14:46:03Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![vongomben](https://avatars.discourse-cdn.com/v4/letter/v/a4c791/32.png) [@vongomben](https://discourse.nodered.org/u/vongomben)\
**Post date:** [16 February 2021 14:46 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/1 "2021-02-16T14:46:03Z")

</div>

Hi andthanks in advance for your help.

I think I'm crashing of my javascript weaknesses, and I'm always trying to avoid functions.  
In this case I am injecting a JSON with with one object, and multiple objects.

For one object I can suimply use the range node, for the array I'm (failing) in using a function.

My questions:

- how would the correct function be?
- how could I use the change node instead of a function, using JSONata?

Feel free to point me to any helpful online documentation

 ![immagine](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/1/c169e4d05b00d22c02f7e4df66972418e98fc887.png)

```auto
[{"id":"aa288e5a.6ead2","type":"inject","z":"63ccda68.bf7a74","name":"insert multiple data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"id\":1,\"first_name\":\"Mariette\",\"last_name\":\"Ulrik\",\"email\":\"mulrik0@gravatar.com\",\"gender\":\"Genderqueer\",\"presence\":75,\"rating\":1,\"experience\":\"Yellow\"},{\"id\":2,\"first_name\":\"Gaspar\",\"last_name\":\"Dunne\",\"email\":\"gdunne1@google.com.au\",\"gender\":\"Agender\",\"presence\":46,\"rating\":3,\"experience\":\"Violet\"},{\"id\":3,\"first_name\":\"Amargo\",\"last_name\":\"Pien\",\"email\":\"apien2@reuters.com\",\"gender\":\"Agender\",\"presence\":95,\"rating\":2,\"experience\":\"Turquoise\"},{\"id\":4,\"first_name\":\"Sylvester\",\"last_name\":\"Dunn\",\"email\":\"sdunn3@abc.net.au\",\"gender\":\"Polygender\",\"presence\":61,\"rating\":1,\"experience\":\"Mauv\"},{\"id\":5,\"first_name\":\"Abbie\",\"last_name\":\"Sharrock\",\"email\":\"asharrock4@reverbnation.com\",\"gender\":\"Genderfluid\",\"presence\":21,\"rating\":1,\"experience\":\"Purple\"},{\"id\":6,\"first_name\":\"Leticia\",\"last_name\":\"Grouvel\",\"email\":\"lgrouvel5@purevolume.com\",\"gender\":\"Female\",\"presence\":38,\"rating\":5,\"experience\":\"Indigo\"},{\"id\":7,\"first_name\":\"Alberta\",\"last_name\":\"Goodfellowe\",\"email\":\"agoodfellowe6@un.org\",\"gender\":\"Female\",\"presence\":78,\"rating\":3,\"experience\":\"Violet\"},{\"id\":8,\"first_name\":\"Alair\",\"last_name\":\"Mindenhall\",\"email\":\"amindenhall7@issuu.com\",\"gender\":\"Non-binary\",\"presence\":30,\"rating\":5,\"experience\":\"Turquoise\"},{\"id\":9,\"first_name\":\"Ulises\",\"last_name\":\"Millan\",\"email\":\"umillan8@symantec.com\",\"gender\":\"Genderfluid\",\"presence\":2,\"rating\":2,\"experience\":\"Purple\"},{\"id\":10,\"first_name\":\"Man\",\"last_name\":\"Brittian\",\"email\":\"mbrittian9@mashable.com\",\"gender\":\"Polygender\",\"presence\":16,\"rating\":2,\"experience\":\"Indigo\"}]","payloadType":"json","x":630,"y":1120,"wires":[["9c83cf10.93e0c"]]},{"id":"e09ad7d8.ebc788","type":"inject","z":"63ccda68.bf7a74","name":"insert one data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"id\":8,\"first_name\":\"Alair\",\"last_name\":\"Mindenhall\",\"email\":\"amindenhall7@issuu.com\",\"gender\":\"Non-binary\",\"presence\":30,\"rating\":5,\"experience\":\"Turquoise\"}","payloadType":"json","x":640,"y":1160,"wires":[["af6577ee.d630b8"]]},{"id":"af6577ee.d630b8","type":"range","z":"63ccda68.bf7a74","minin":"1","maxin":"5","minout":"1","maxout":"1000","action":"scale","round":true,"property":"payload.rating","name":"Map one \"rating\"","x":840,"y":1160,"wires":[["5c57d753.c27ed8"]]},{"id":"5c57d753.c27ed8","type":"debug","z":"63ccda68.bf7a74","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1050,"y":1140,"wires":[]},{"id":"9c83cf10.93e0c","type":"function","z":"63ccda68.bf7a74","name":"Map all \"ratings\"","func":"// Javascript doesn't have built-in support for ranges\n// Insted we use arrays of two elements to represent ranges\n\n// Javascript doesn't have built-in support for ranges\n// Insted we use arrays of two elements to represent ranges\nvar mapRange = function(from, to, s) {\n return to[0] + (s - from[0]) * (to[1] - to[0]) / (from[1] - from[0]);\n};\n \noutput = {};\n\nfor (var i of msg.payload) {\n output[i].rating = mapRange([0, 10], [-1, 0], i.rating);\n}\nmsg.payload = output;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":840,"y":1120,"wires":[["5c57d753.c27ed8"]]}]

```

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [16 February 2021 15:13 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/2 "2021-02-16T15:13:49Z")

</div>

Something like this is the corrected version of your function

```auto
// Javascript doesn't have built-in support for ranges
// Insted we use arrays of two elements to represent ranges

// Javascript doesn't have built-in support for ranges
// Insted we use arrays of two elements to represent ranges
var mapRange = function(from, to, s) {
  return to[0] + (s - from[0]) * (to[1] - to[0]) / (from[1] - from[0]);
};
 
output = []

for (let i=0; i<msg.payload.length; i++) {
    output[i] = {rating: mapRange([0, 10], [-1, 0], msg.payload[i].rating)};
}
msg.payload = output;

return msg;

```

However, that returns only the scaled rating and loses the rest of the data. Is that what you want to do or do you want to keep the rest of the data intact?

---

<div class="post-metadata">

**Author:** ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)\
**Post date:** [16 February 2021 15:25 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/3 "2021-02-16T15:25:11Z")

</div>

If you still want to avoid using Javascript `function` nodes, here is a more "node-red" way of scaling multiple objects:

Whether you have 1 or an array of many objects, you can `split` the incoming array into one object per msg -\> use `range` to scale the value just like you did with one object -\> then `join` the stream back into an array of scaled objects.

---

<div class="post-metadata">

**Author:** ![vongomben](https://avatars.discourse-cdn.com/v4/letter/v/a4c791/32.png) [@vongomben](https://discourse.nodered.org/u/vongomben)\
**Post date:** [16 February 2021 16:36 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/4 "2021-02-16T16:36:28Z")

</div>

@shrickus thanks for pointing it out: yes, I mainly want to avoind use functions because I'm feeling quite weak in jasascript (but obviously I will have to face this at some point).  
I solved the non coding solution with the profitable combination of `split` and `join`, with a `range` in between.

Still, the question raised by @colin remains: I wanted to change that specific paramenter.  
Oviously your function overrides all content of the object.

Why this code is not preserving it (is not touching that parameter)?  
How do I achieve the split / join solution?

```auto
// Javascript doesn't have built-in support for ranges
// Insted we use arrays of two elements to represent ranges

// Javascript doesn't have built-in support for ranges
// Insted we use arrays of two elements to represent ranges
var mapRange = function(from, to, s) {
  return to[0] + (s - from[0]) * (to[1] - to[0]) / (from[1] - from[0]);
};
 
output = []

for (let i=0; i<msg.payload.length; i++) {
    output[i] = {rating: mapRange([0, 5], [0, 1000], msg.payload[i].rating)};
}
msg.payload.rating = output;

return msg;

```

My flow:

```auto
[{"id":"aa288e5a.6ead2","type":"inject","z":"63ccda68.bf7a74","name":"insert multiple data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"id\":1,\"first_name\":\"Mariette\",\"last_name\":\"Ulrik\",\"email\":\"mulrik0@gravatar.com\",\"gender\":\"Genderqueer\",\"presence\":75,\"rating\":1,\"experience\":\"Yellow\"},{\"id\":2,\"first_name\":\"Gaspar\",\"last_name\":\"Dunne\",\"email\":\"gdunne1@google.com.au\",\"gender\":\"Agender\",\"presence\":46,\"rating\":3,\"experience\":\"Violet\"},{\"id\":3,\"first_name\":\"Amargo\",\"last_name\":\"Pien\",\"email\":\"apien2@reuters.com\",\"gender\":\"Agender\",\"presence\":95,\"rating\":2,\"experience\":\"Turquoise\"},{\"id\":4,\"first_name\":\"Sylvester\",\"last_name\":\"Dunn\",\"email\":\"sdunn3@abc.net.au\",\"gender\":\"Polygender\",\"presence\":61,\"rating\":1,\"experience\":\"Mauv\"},{\"id\":5,\"first_name\":\"Abbie\",\"last_name\":\"Sharrock\",\"email\":\"asharrock4@reverbnation.com\",\"gender\":\"Genderfluid\",\"presence\":21,\"rating\":1,\"experience\":\"Purple\"},{\"id\":6,\"first_name\":\"Leticia\",\"last_name\":\"Grouvel\",\"email\":\"lgrouvel5@purevolume.com\",\"gender\":\"Female\",\"presence\":38,\"rating\":5,\"experience\":\"Indigo\"},{\"id\":7,\"first_name\":\"Alberta\",\"last_name\":\"Goodfellowe\",\"email\":\"agoodfellowe6@un.org\",\"gender\":\"Female\",\"presence\":78,\"rating\":3,\"experience\":\"Violet\"},{\"id\":8,\"first_name\":\"Alair\",\"last_name\":\"Mindenhall\",\"email\":\"amindenhall7@issuu.com\",\"gender\":\"Non-binary\",\"presence\":30,\"rating\":5,\"experience\":\"Turquoise\"},{\"id\":9,\"first_name\":\"Ulises\",\"last_name\":\"Millan\",\"email\":\"umillan8@symantec.com\",\"gender\":\"Genderfluid\",\"presence\":2,\"rating\":2,\"experience\":\"Purple\"},{\"id\":10,\"first_name\":\"Man\",\"last_name\":\"Brittian\",\"email\":\"mbrittian9@mashable.com\",\"gender\":\"Polygender\",\"presence\":16,\"rating\":2,\"experience\":\"Indigo\"}]","payloadType":"json","x":150,"y":1240,"wires":[["4d455c0f.488494","b1779747.a9c788"]]},{"id":"5c57d753.c27ed8","type":"debug","z":"63ccda68.bf7a74","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":630,"y":1220,"wires":[]},{"id":"a6e810c5.38af1","type":"range","z":"63ccda68.bf7a74","minin":"1","maxin":"5","minout":"1","maxout":"1000","action":"scale","round":true,"property":"payload.rating","name":"Map one \"rating\"","x":440,"y":1320,"wires":[["28148edd.286a92"]]},{"id":"d5a86486.8a8188","type":"debug","z":"63ccda68.bf7a74","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":670,"y":1260,"wires":[]},{"id":"4d455c0f.488494","type":"split","z":"63ccda68.bf7a74","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":true,"addname":"","x":330,"y":1260,"wires":[["a6e810c5.38af1"]]},{"id":"28148edd.286a92","type":"join","z":"63ccda68.bf7a74","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":510,"y":1260,"wires":[["d5a86486.8a8188"]]},{"id":"b1779747.a9c788","type":"function","z":"63ccda68.bf7a74","name":"Map all \"ratings\"","func":"// Javascript doesn't have built-in support for ranges\n// Insted we use arrays of two elements to represent ranges\n\n// Javascript doesn't have built-in support for ranges\n// Insted we use arrays of two elements to represent ranges\nvar mapRange = function(from, to, s) {\n return to[0] + (s - from[0]) * (to[1] - to[0]) / (from[1] - from[0]);\n};\n \noutput = []\n\nfor (let i=0; i<msg.payload.length; i++) {\n output[i] = {rating: mapRange([0, 5], [0, 1000], msg.payload[i].rating)};\n}\nmsg.payload.rating = output;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":400,"y":1220,"wires":[["5c57d753.c27ed8"]]}]

```

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [16 February 2021 17:06 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/5 "2021-02-16T17:06:14Z")

</div>

To preserve the object use

function

```auto
var mapRange = function(from, to, s) {
  return to[0] + (s - from[0]) * (to[1] - to[0]) / (from[1] - from[0]);
};
for (let i=0; i<msg.payload.length; i++) {
    msg.payload[i].rating = mapRange([0, 5], [0, 1000], msg.payload[i].rating);
}
return msg;

```

JSONata in change node

```auto
($to:=[0,1000];	
$from:=[0,5];	
payload ~> |*|{'rating': ($to[0] + (rating - $from[0]) * ($to[1] - $to[0]) / ($from[1] - $from[0]))}|	)	

```

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [16 February 2021 17:13 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/6 "2021-02-16T17:13:47Z")

</div>

> [@vongomben](#):
>
> Why this code is not preserving it (is not touching that parameter)?

Because it creates a new array `output` which only contains the rating, and returns that in the payload. To keep the original data try this

```auto
var mapRange = function(from, to, s) {
  return to[0] + (s - from[0]) * (to[1] - to[0]) / (from[1] - from[0]);
};

for (let i=0; i<msg.payload.length; i++) {
    msg.payload[i].rating = mapRange([0, 10], [-1, 0], msg.payload[i].rating);
}

return msg;

```

You could also do it a little more neatly using the `Array.map()` method but that may not be the best solution in this case as it would create a completely new array which is a copy of the original, with the rating changed. That wouldn't matter if the array is small but if there were thousands or tens of thousands of lines then it might not be a good idea. Similarly the split and re-join method would be perfectly ok for small arrays but not a good idea if it were large. It could also be done in JSONata, but again I think it would make a copy of the array like the map function.

---

<div class="post-metadata">

**Author:** ![vongomben](https://avatars.discourse-cdn.com/v4/letter/v/a4c791/32.png) [@vongomben](https://discourse.nodered.org/u/vongomben)\
**Post date:** [17 February 2021 14:25 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/7 "2021-02-17T14:25:08Z")

</div>

thanks both!  
I'm testing and editing this.

Thanks!

---

<div class="post-metadata">

**Author:** ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)\
**Post date:** [17 February 2021 20:24 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/8 "2021-02-17T20:24:32Z")

</div>

> [@Colin](#):
>
> Similarly the split and re-join method would be perfectly ok for small arrays but not a good idea if it were large. It could also be done in JSONata, but again I think it would make a copy of the array like the map function.

Colin, good point on the data copy (potential) issue...

In that case, I think the JSONata Object transformation expression from @E1cid would be the best approach, since it changes the data inline, instead of making a copy. At least that's what I get from reading the docs on this [admittedly esoteric function](http://docs.jsonata.org/other-operators#-------transform)...

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [17 February 2021 21:07 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/9 "2021-02-17T21:07:45Z")

</div>

> [@shrickus](#):
>
> I think the JSONata Object transformation expression from @E1cid would be the bestsince it changes the data inline, instead of making a copy.

My reading is that it makes a copy. It says

where  
head evaluates to the object that is to be copied and transformed

---

<div class="post-metadata">

**Author:** ![vongomben](https://avatars.discourse-cdn.com/v4/letter/v/a4c791/32.png) [@vongomben](https://discourse.nodered.org/u/vongomben)\
**Post date:** [23 February 2021 08:43 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/10 "2021-02-23T08:43:16Z")

</div>

Thanks both!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [24 April 2021 08:43 UTC](https://discourse.nodered.org/t/mapping-a-specific-data-of-an-array-of-properties-in-json/41092/11 "2021-04-24T08:43:44Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
